- 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 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: help:
@echo @echo
@ -196,13 +196,12 @@ infos-xml:
do \ do \
intltool-merge -x po/glasnost-web/ $$F `dirname $$F`/`basename $$F .in`; \ intltool-merge -x po/glasnost-web/ $$F `dirname $$F`/`basename $$F .in`; \
done done
install-create-dir: install-create-dir:
-mkdir -p "$(DESTDIR)/$(BIN_DIR)" -mkdir -p "$(DESTDIR)/$(BIN_DIR)"
-mkdir -p "$(DESTDIR)/$(DATA_DIR)" -mkdir -p "$(DESTDIR)/$(DATA_DIR)"
-mkdir -p "$(DESTDIR)/$(GLASNOST_DIR)" -mkdir -p "$(DESTDIR)/$(GLASNOST_DIR)"
-mkdir -p "$(DESTDIR)/$(ETC_DIR)" -mkdir -p "$(DESTDIR)/$(ETC_DIR)"
-mkdir -p "$(DESTDIR)/etc/init.d"
-mkdir -p "$(DESTDIR)/$(EXTENSIONS_DIR)" -mkdir -p "$(DESTDIR)/$(EXTENSIONS_DIR)"
-mkdir -p "$(DESTDIR)/$(LIBS_DIR)" -mkdir -p "$(DESTDIR)/$(LIBS_DIR)"
-mkdir -p "$(DESTDIR)/$(LOCALE_DIR)" -mkdir -p "$(DESTDIR)/$(LOCALE_DIR)"
@ -214,9 +213,9 @@ install-create-dir:
-mkdir -p "$(DESTDIR)/$(TEMPLATES_DIR)" -mkdir -p "$(DESTDIR)/$(TEMPLATES_DIR)"
-mkdir -p "$(DESTDIR)/$(WEB_DIR)" -mkdir -p "$(DESTDIR)/$(WEB_DIR)"
install-glasnost: config install-glasnost: config profiles-xml
@mkdir -p "$(DESTDIR)/$(GLASNOST_DIR)" @mkdir -p "$(DESTDIR)/$(GLASNOST_DIR)"
-cp $^ "$(DESTDIR)/$(GLASNOST_DIR)"/ -cp config "$(DESTDIR)/$(GLASNOST_DIR)"/
@if test -e "$(DESTDIR)/$(SBIN_DIR)/$(GLASNOST)"; then \ @if test -e "$(DESTDIR)/$(SBIN_DIR)/$(GLASNOST)"; then \
rm -f "$(DESTDIR)/$(SBIN_DIR)/$(GLASNOST)"; \ rm -f "$(DESTDIR)/$(SBIN_DIR)/$(GLASNOST)"; \
else :; fi else :; fi
@ -234,6 +233,8 @@ install-glasnost: config
test ! -e "$(DESTDIR)/$(ETC_DIR)/config" || \ test ! -e "$(DESTDIR)/$(ETC_DIR)/config" || \
cp "$(DESTDIR)/$(ETC_DIR)/config" "$(DESTDIR)/$(ETC_DIR)/config.save" cp "$(DESTDIR)/$(ETC_DIR)/config" "$(DESTDIR)/$(ETC_DIR)/config.save"
test -e "$(DESTDIR)/$(ETC_DIR)/config" || cp config "$(DESTDIR)/$(ETC_DIR)/config" 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: install-data:
@if ! test -e "$(DESTDIR)/$(DATA_DIR)"; then \ @if ! test -e "$(DESTDIR)/$(DATA_DIR)"; then \
@ -309,7 +310,7 @@ install-templates: infos-xml
-mkdir -p "$(DESTDIR)/$(TEMPLATES_DIR)" -mkdir -p "$(DESTDIR)/$(TEMPLATES_DIR)"
for F in $(TEMPLATES); \ for F in $(TEMPLATES); \
do \ 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 done
install-web: 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/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 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/ talTranslations.py: templates/
./talGettext.py templates/ > talTranslations.py ./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/fi.po po/glasnost-web/fi.pox
cp po/glasnost-web/fr.po po/glasnost-web/fr.pox cp po/glasnost-web/fr.po po/glasnost-web/fr.pox
cp po/glasnost-web/sv.po po/glasnost-web/sv.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 \ do \
intltool-extract --type=gettext/xml $$F; \ intltool-extract --type=gettext/xml $$F; \
done done
$(GETTEXT) -d po/glasnost-web/messages -k N_ `$(FIND) $^ -type f -name "*.py"` \ $(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/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/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 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) # Cache files? (boolean, default: false)
CacheFiles = false CacheFiles = false
# Domains to use for translations going through gettext (don't change)
GettextDomains = glasnost-web
Per dispatcher options Per dispatcher options
---------------------- ----------------------
@ -80,9 +77,6 @@ Debug:
DisableSpellchecking: DisableSpellchecking:
Disable spellchecking (used in <textarea> previews). (default: false) Disable spellchecking (used in <textarea> previews). (default: false)
GettextDomains:
Allows to add more gettext domains to look in for translations.
Profiling: Profiling:
Dumps profiling informations into /tmp/ Dumps profiling informations into /tmp/
(default: false) (default: false)
@ -108,18 +102,10 @@ WebDirectoryPath:
Define an additional path where to look for .py files after site Define an additional path where to look for .py files after site
DocumentRoot and before Glasnost-wide WebDirectoryPath. 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 Per server options
------------------ ------------------
OnlyForDispatchers
ServerHostName ServerHostName
ServerPort 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. * 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 glasnost (0.6.5-1) unstable; urgency=low

View File

@ -1106,13 +1106,8 @@ class Application(applications.Application):
except locale.Error: except locale.Error:
locale.setlocale(locale.LC_COLLATE, 'C') locale.setlocale(locale.LC_COLLATE, 'C')
domains = [ domains = [ '%s-web' % glasnost.applicationName ] + (
commonTools.getConfig( virtualHost.locales or [])
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(',')]
translation = commonTools.translation(domains, languages) translation = commonTools.translation(domains, languages)
__builtin__.__dict__['_'] = translation.gettext __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 from glasnost.proxy.tools import getProxyForServerRole
articleId = sys.argv[1] articleId = sys.argv[1]
dispatcherId = 'glasnost://' + splitObjectId(articleId)[0] dispatcherId = commonTools.extractDispatcherId(articleId)
init(dispatcherId) init(dispatcherId)

View File

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

View File

@ -55,7 +55,7 @@ import glasnost
from glasnost.common.AppointmentsCommon import * from glasnost.common.AppointmentsCommon import *
import glasnost.common.faults as faults 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 import glasnost.common.tools_new as commonTools
from glasnost.server.ObjectsServer import ObjectServerMixin, \ from glasnost.server.ObjectsServer import ObjectServerMixin, \
@ -174,63 +174,12 @@ class AppointmentsServer(AppointmentsCommonMixin, ObjectsServer):
def addObjectXmlRpc(self, objectImport): def addObjectXmlRpc(self, objectImport):
objectId = ObjectsServer.addObjectXmlRpc(self, objectImport) objectId = ObjectsServer.addObjectXmlRpc(self, objectImport)
return objectId # TODO: send notification mail
# 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)
return objectId return objectId
def modifyObjectXmlRpc(self, objectImport): def modifyObjectXmlRpc(self, objectImport):
version = ObjectsServer.modifyObjectXmlRpc(self, objectImport) version = ObjectsServer.modifyObjectXmlRpc(self, objectImport)
virtualServerId = context.getVar('applicationId') # TODO: send notification mail
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)
return version return version
def updateFromVCalendar(self, vCalendar): def updateFromVCalendar(self, vCalendar):

View File

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

View File

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

View File

@ -110,12 +110,20 @@ class CommentsServer(CommentsCommonMixin, ObjectsServer):
def canGetObjects(self): def canGetObjects(self):
return 0 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') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
tempResult = [] tempResult = []
for objectId, objectCore in virtualServer.objects.items(): for objectId, objectCore in virtualServer.objects.items():
if self.getParentId(objectCore) == parentId: if self.getParentId(objectCore) == parentId and \
objectCore.isEditorial == isEditorial:
tempResult.append(objectId) tempResult.append(objectId)
result = [] result = []
for objectId in tempResult: for objectId in tempResult:
@ -133,6 +141,7 @@ class CommentsServer(CommentsCommonMixin, ObjectsServer):
def registerPublicMethods(self): def registerPublicMethods(self):
ObjectsServer.registerPublicMethods(self) ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('canPostEditorialComment')
self.registerPublicMethod('getObjectIdsWithParent') self.registerPublicMethod('getObjectIdsWithParent')
commentsServer = CommentsServer() commentsServer = CommentsServer()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -47,8 +47,11 @@ __version__ = '$Revision$'[11:-2]
from fnmatch import fnmatch from fnmatch import fnmatch
import os
import sgmllib
import sys import sys
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir) sys.path.insert(0, glasnostPythonDir)
@ -78,11 +81,62 @@ class AdminVirtualHosts(AdminServerMixin, AdminVirtualHostsCommon):
register(AdminVirtualHosts) 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): class VirtualHost(ObjectServerMixin, VirtualHostCommon):
strings = None def acquireNonCore(self, objectDirectoryPath = None,
strings_keyType = 'string' dataDirectoryPath = None, parentSlot = None):
strings_type = 'mapping' ObjectServerMixin.acquireNonCore(
strings_valueType = 'string' 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): def checkModifyIsPossible(self, changes, givenSlotNames = None):
ObjectServerMixin.checkModifyIsPossible( ObjectServerMixin.checkModifyIsPossible(
@ -110,6 +164,14 @@ class VirtualHost(ObjectServerMixin, VirtualHostCommon):
del objectsByHostName[hostName] del objectsByHostName[hostName]
if self.hostName is not None: if self.hostName is not None:
objectsByHostName[self.hostName] = self 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) register(VirtualHost)
@ -204,7 +266,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
virtualServer.markObjectAsDirty(object) virtualServer.markObjectAsDirty(object)
newDispatcherId = object.defaultDispatcherId newDispatcherId = object.defaultDispatcherId
registerDispatcherId(newDispatcherId) registerDispatcherId(newDispatcherId, object.profiles)
newVirtualServerId = commonTools.makeApplicationId( newVirtualServerId = commonTools.makeApplicationId(
newDispatcherId, self.applicationRole) newDispatcherId, self.applicationRole)
context.push( context.push(
@ -237,19 +299,29 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
"""Return the url of the virtual server.""" """Return the url of the virtual server."""
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
print 'getHostName for', virtualServerId
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
dispatcherId = commonTools.extractDispatcherId( dispatcherId = commonTools.extractDispatcherId(
virtualServerId).lower() virtualServerId).lower()
for object in virtualServer.objects.values(): for object in virtualServer.objects.values():
if dispatcherId == commonTools.extractDispatcherId( if dispatcherId == commonTools.extractDispatcherId(
object.defaultDispatcherId).lower(): object.defaultDispatcherId).lower():
return utf8('http://' + object.hostName) return utf8(object.hostName)
raise faults.MissingItem(dispatcherId) raise faults.MissingItem(dispatcherId)
def getObjectByHostName(self, hostName): def getObjectByHostNameXmlRpc(self, hostName):
"""Return the virtual host with the given host name.""" 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') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
askedHostName = hostName askedHostName = hostName
@ -261,6 +333,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
object.hostName = hostName object.hostName = hostName
object.defaultDispatcherId = 'glasnost://%s' % hostName object.defaultDispatcherId = 'glasnost://%s' % hostName
object.language = 'en' object.language = 'en'
object.profiles = ['basic', 'cms', 'vote']
object.writersSet = [system.generalPublicId] object.writersSet = [system.generalPublicId]
object.readersSet = [system.generalPublicId] object.readersSet = [system.generalPublicId]
context.push(noVirtualHost = 1) context.push(noVirtualHost = 1)
@ -284,17 +357,13 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
virtualServer.admin.defaultVirtualHostId] virtualServer.admin.defaultVirtualHostId]
except KeyError: except KeyError:
raise faults.MissingItem(hostName) raise faults.MissingItem(hostName)
return object return object.id
object = virtualServer.objectsByHostName[hostName] object = virtualServer.objectsByHostName[hostName]
return object return object.id
def getObjectByHostNameXmlRpc(self, hostName):
hostName = iso8859_15(hostName)
return self.getObjectByHostName(hostName).exportToXmlRpc()
def getObjectIdByHostNameXmlRpc(self, hostName): def getObjectIdByHostNameXmlRpc(self, hostName):
hostName = iso8859_15(hostName) hostName = iso8859_15(hostName)
return self.getObjectByHostName(hostName).id return self.getObjectIdByHostName(hostName)
def hasDispatcherIdXmlRpc(self, dispatcherId): def hasDispatcherIdXmlRpc(self, dispatcherId):
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
@ -329,11 +398,18 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
return ObjectsServer.isAdmin(self) return ObjectsServer.isAdmin(self)
def modifyObjectXmlRpc(self, objectImport): def modifyObjectXmlRpc(self, objectImport):
version = ObjectsServer.modifyObjectXmlRpc(self, objectImport)
id = objectImport['id'] id = objectImport['id']
virtualServerId = context.getVar('applicationId') virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId) virtualServer = self.getVirtualServer(virtualServerId)
oldObject = virtualServer.loadObjectCore(id)
version = ObjectsServer.modifyObjectXmlRpc(self, objectImport)
object = virtualServer.loadObjectCore(id) 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) self.updateApacheVHost(object)
return version return version
@ -352,7 +428,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
ObjectsServer.registerToDispatcher(self) ObjectsServer.registerToDispatcher(self)
for virtualHost in self.virtualServer.objects.values(): for virtualHost in self.virtualServer.objects.values():
newDispatcherId = virtualHost.defaultDispatcherId newDispatcherId = virtualHost.defaultDispatcherId
registerDispatcherId(newDispatcherId) registerDispatcherId(newDispatcherId, virtualHost.profiles)
newVirtualServerId = commonTools.makeApplicationId( newVirtualServerId = commonTools.makeApplicationId(
newDispatcherId, self.applicationRole) newDispatcherId, self.applicationRole)
context.push( context.push(
@ -390,6 +466,7 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
object.defaultDispatcherId = object.defaultDispatcherId[ object.defaultDispatcherId = object.defaultDispatcherId[
:-1] :-1]
changed = 1 changed = 1
if changed: if changed:
virtualServer.markAllAsDirtyFIXME() virtualServer.markAllAsDirtyFIXME()
@ -450,6 +527,11 @@ class VirtualHostsServer(VirtualHostsCommonMixin, ObjectsServer):
virtualServer.objectsByHostName[object.hostName] = object virtualServer.objectsByHostName[object.hostName] = object
virtualServer.markCoreAsDirty() virtualServer.markCoreAsDirty()
def upgrade_0001_0027(self, virtualServer):
for object in virtualServer.objects.values():
object.profiles = ['basic', 'cms', 'vote', 'translations']
virtualServer.markCoreAsDirty()
virtualHostsServer = VirtualHostsServer() virtualHostsServer = VirtualHostsServer()

View File

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

View File

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

View File

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

View File

@ -193,11 +193,11 @@ class ObjectsCommonMixin:
The capitalized 'gettextized' handled object class name string. The capitalized 'gettextized' handled object class name string.
*objectsName*: *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...)). without the type (proxy or server, etc...)).
*objectsNameCapitalized*: *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...)). without the type (proxy or server, etc...)).
*serverRole*: *serverRole*:

View File

@ -257,11 +257,11 @@ class PeopleCommonMixin(ObjectsCommonMixin):
The capitalized 'gettextized' handled object class name string. The capitalized 'gettextized' handled object class name string.
*objectsName*: *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...)). without the type (proxy or server, etc...)).
*objectsNameCapitalized*: *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...)). without the type (proxy or server, etc...)).
*serverRole*: *serverRole*:

View File

@ -51,6 +51,7 @@ from ObjectsCommon import AdminCommon, ObjectCommon, ObjectsCommonMixin
import system import system
import glasnost.common.context as context import glasnost.common.context as context
import glasnost.common.tools_new as commonTools
class AdminVirtualHostsCommon(AdminCommon): class AdminVirtualHostsCommon(AdminCommon):
defaultVirtualHostId = None defaultVirtualHostId = None
@ -91,6 +92,28 @@ class VirtualHostInfoParser(sgmllib.SGMLParser):
self.label += data 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): class VirtualHostCommon(ObjectCommon):
"""Virtual host super class used to be inherited with a Mixin Class. """Virtual host super class used to be inherited with a Mixin Class.
@ -102,6 +125,21 @@ class VirtualHostCommon(ObjectCommon):
creationTime = None creationTime = None
creationTime_kindName = 'CreationTime' 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 = None
defaultDispatcherId_kind_balloonHelp = N_( defaultDispatcherId_kind_balloonHelp = N_(
'Enter the Glasnost dispatcher id for this virtual host '\ 'Enter the Glasnost dispatcher id for this virtual host '\
@ -128,8 +166,42 @@ class VirtualHostCommon(ObjectCommon):
modificationTime = None modificationTime = None
modificationTime_kindName = 'ModificationTime' 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 = None
readersSet_kind_itemKind_value_defaultValue = system.generalPublicId readersSet_defaultValue = [system.generalPublicId]
readersSet_kindName = 'ReadersSet' readersSet_kindName = 'ReadersSet'
serverRole = 'virtualhosts' serverRole = 'virtualhosts'
@ -144,7 +216,7 @@ class VirtualHostCommon(ObjectCommon):
isRequired = 1 isRequired = 1
defaultValue = 'glasnost2' defaultValue = 'glasnost2'
label = N_('Template') label = N_('Template')
def getValues(self, slot, fields): def getValues(self, slot):
templatesDirectoryPath = context.getVar('templatesDirectoryPath') templatesDirectoryPath = context.getVar('templatesDirectoryPath')
dirs = os.listdir(templatesDirectoryPath) dirs = os.listdir(templatesDirectoryPath)
values = [] values = []
@ -155,9 +227,9 @@ class VirtualHostCommon(ObjectCommon):
values.sort() values.sort()
return values return values
def getLabels(self, slot, fields): def getLabels(self, slot):
templatesDirectoryPath = context.getVar('templatesDirectoryPath') templatesDirectoryPath = context.getVar('templatesDirectoryPath')
dirs = self.getValues(slot, fields) dirs = self.getValues(slot)
labels = {} labels = {}
for d in dirs: for d in dirs:
infosName = os.path.join(templatesDirectoryPath, d, 'infos.xml') infosName = os.path.join(templatesDirectoryPath, d, 'infos.xml')
@ -249,11 +321,11 @@ class VirtualHostsCommonMixin(ObjectsCommonMixin):
The capitalized 'gettextized' handled object class name string. The capitalized 'gettextized' handled object class name string.
*objectsName*: *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...)). without the type (proxy or server, etc...)).
*objectsNameCapitalized*: *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...)). without the type (proxy or server, etc...)).
*serverRole*: *serverRole*:

View File

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

View File

@ -92,6 +92,7 @@ faultCodeStringNotAvailableThroughGettext = 39
faultCodeUnknownCommandAction = 40 faultCodeUnknownCommandAction = 40
faultCodeValueTooBig = 41 faultCodeValueTooBig = 41
faultCodeValueTooSmall = 42 faultCodeValueTooSmall = 42
faultCodeRoleNotInProfiles = 43
faultCodeUnknownVoteToken = 1000 faultCodeUnknownVoteToken = 1000
faultCodeUnknownVoterToken = 1001 faultCodeUnknownVoterToken = 1001
@ -552,6 +553,12 @@ class ValueTooBig(BaseFault):
return 'Value (= %s) too big for slot "%s"' % (value, slot) 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. # Dataflow.

View File

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

View File

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

View File

@ -353,36 +353,6 @@ Content-Type: application/octet-stream
raise faults.SmtpError() 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): def utf8(s):
"""Convert a string from iso-8859-15 to utf-8.""" """Convert a string from iso-8859-15 to utf-8."""
if type(s) == types.UnicodeType: if type(s) == types.UnicodeType:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -66,11 +66,11 @@ def getObjectLabelsTranslated(ids, destinationLanguages):
while remainingIds: while remainingIds:
id = remainingIds[0] id = remainingIds[0]
del remainingIds[0] del remainingIds[0]
serverHostNameAndPort, serverRole, localId = splitObjectId(id) serverHostNameAndPort, serverRole, localId = commonTools.splitId(id)
proxyIds = [id] proxyIds = [id]
remainingIds2 = remainingIds[:] remainingIds2 = remainingIds[:]
for id2 in remainingIds2: for id2 in remainingIds2:
serverHostNameAndPort2, serverRole2, localId2 = splitObjectId(id2) serverHostNameAndPort2, serverRole2, localId2 = commonTools.splitId(id2)
if serverHostNameAndPort2 == serverHostNameAndPort \ if serverHostNameAndPort2 == serverHostNameAndPort \
and serverRole2 == serverRole: and serverRole2 == serverRole:
proxyIds.append(id2) proxyIds.append(id2)
@ -170,7 +170,7 @@ def sortIds(ids):
return [] return []
idsByServer = {} idsByServer = {}
for id in ids: for id in ids:
serverHostNameAndPort, serverRole, localId = splitObjectId(id) serverHostNameAndPort, serverRole, localId = commonTools.splitId(id)
serverId = commonTools.extractServerId(id) serverId = commonTools.extractServerId(id)
if not idsByServer.has_key(serverId): if not idsByServer.has_key(serverId):
proxy = getProxyForServerRole(serverRole) proxy = getProxyForServerRole(serverRole)
@ -184,7 +184,7 @@ def sortIds(ids):
serverIds.sort() serverIds.sort()
result = [] result = []
for serverId in serverIds: for serverId in serverIds:
serverHostNameAndPort, serverRole = splitApplicationId(serverId) serverNameAndPort, serverRole, mu = commonTools.splitId(serverId)
proxy = getProxyForServerRole(serverRole) proxy = getProxyForServerRole(serverRole)
ids = idsByServer[serverId] ids = idsByServer[serverId]
sortedIds = proxy.sortObjectIds(ids, serverId = serverId, forceIds = 1) 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 All methods can be overriden or extended, in fact, this class define their
default behavior. 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 id_kind_isAutomaticallyModified = 1
@ -108,7 +108,7 @@ class ObjectServerMixin(things.ThingMixin):
"""Load the data associated with the object. """Load the data associated with the object.
The datas are loaded, but the metadata are in the object instance. 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: Keyword arguments:
================== ==================
@ -135,8 +135,8 @@ class ObjectServerMixin(things.ThingMixin):
dataDirectoryPath = virtualServer.dataDirectoryPath dataDirectoryPath = virtualServer.dataDirectoryPath
objectsDirectoryPath = os.path.join( objectsDirectoryPath = os.path.join(
dataDirectoryPath, server.applicationRole) dataDirectoryPath, server.applicationRole)
serverHostNameAndPort, serverRole, localId = splitObjectId( serverHostNameAndPort, serverRole, localId = \
self.id) commonTools.splitId(self.id)
objectDirectoryPath = os.path.join( objectDirectoryPath = os.path.join(
objectsDirectoryPath, localId) objectsDirectoryPath, localId)
things.ThingMixin.acquireNonCore( things.ThingMixin.acquireNonCore(
@ -145,10 +145,7 @@ class ObjectServerMixin(things.ThingMixin):
def canBeCreatedByClient(self): def canBeCreatedByClient(self):
"""Indicate whether the client application can create an object.""" """Indicate whether the client application can create an object."""
clientToken = context.getVar('clientToken') return 0
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
return clientRole == 'workflows'
def canBeDeletedByClient(self): def canBeDeletedByClient(self):
"""Indicate whether the client application can delete the object.""" """Indicate whether the client application can delete the object."""
@ -158,10 +155,7 @@ class ObjectServerMixin(things.ThingMixin):
def canBeGottenByClient(self): def canBeGottenByClient(self):
"""Indicate whether the client application can get the object.""" """Indicate whether the client application can get the object."""
clientToken = context.getVar('clientToken') return 0
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
return clientRole == 'workflows'
def canBeModified(self): def canBeModified(self):
"""Indicate whether the object can be modified.""" """Indicate whether the object can be modified."""
@ -171,10 +165,7 @@ class ObjectServerMixin(things.ThingMixin):
def canBeModifiedByClient(self): def canBeModifiedByClient(self):
"""Indicate whether the client application can modify the object.""" """Indicate whether the client application can modify the object."""
clientToken = context.getVar('clientToken') return 0
clientId = getApplicationId(clientToken)
clientNameAndPort, clientRole = splitApplicationId(clientId)
return clientRole == 'workflows'
def checkAddIsPossible(self): def checkAddIsPossible(self):
"""Indicate whether the object can be added to the server dictionnary. """Indicate whether the object can be added to the server dictionnary.
@ -319,7 +310,7 @@ class ObjectServerMixin(things.ThingMixin):
dataDirectoryPath = None, parentSlot = None): dataDirectoryPath = None, parentSlot = None):
"""Remove the object datas from memory. """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: Keyword arguments:
================== ==================
@ -350,7 +341,8 @@ class ObjectServerMixin(things.ThingMixin):
dataDirectoryPath, server.applicationRole) dataDirectoryPath, server.applicationRole)
if not os.access(objectsDirectoryPath, os.F_OK): if not os.access(objectsDirectoryPath, os.F_OK):
return return
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id) serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
objectDirectoryPath = os.path.join(objectsDirectoryPath, localId) objectDirectoryPath = os.path.join(objectsDirectoryPath, localId)
if not os.access(objectDirectoryPath, os.F_OK): if not os.access(objectDirectoryPath, os.F_OK):
return return
@ -364,7 +356,7 @@ class ObjectServerMixin(things.ThingMixin):
parentSlot = None): parentSlot = None):
"""Save the object datas. """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: Keyword arguments:
================== ==================
@ -399,7 +391,8 @@ class ObjectServerMixin(things.ThingMixin):
if not os.access(objectsDirectoryPath, os.F_OK): if not os.access(objectsDirectoryPath, os.F_OK):
os.mkdir(objectsDirectoryPath) os.mkdir(objectsDirectoryPath)
os.chmod(objectsDirectoryPath, 0750) os.chmod(objectsDirectoryPath, 0750)
serverHostNameAndPort, serverRole, localId = splitObjectId(self.id) serverHostNameAndPort, serverRole, localId = \
commonTools.splitId(self.id)
objectDirectoryPath = os.path.join(objectsDirectoryPath, localId) objectDirectoryPath = os.path.join(objectsDirectoryPath, localId)
if os.access(objectDirectoryPath, os.F_OK): if os.access(objectDirectoryPath, os.F_OK):
try: try:
@ -739,7 +732,6 @@ class Server(things.BaseThing, applications.Application):
hasMultipleVirtualServers = 1 hasMultipleVirtualServers = 1
hostName = None hostName = None
isThreaded = 1 isThreaded = 1
onlyForDispatcherIds = None
port = None port = None
rpcServer = None rpcServer = None
thingCategory = 'server' thingCategory = 'server'
@ -756,12 +748,14 @@ class Server(things.BaseThing, applications.Application):
# TODO: check on clientToken (only dispatcher we registered to should # TODO: check on clientToken (only dispatcher we registered to should
# be allowed) # be allowed)
if self.hasMultipleVirtualServers and self.onlyForDispatcherIds \
and not newDispatcherId in self.onlyForDispatcherIds:
return
newVirtualServerId = commonTools.makeApplicationId( newVirtualServerId = commonTools.makeApplicationId(
newDispatcherId, self.applicationRole) newDispatcherId, self.applicationRole)
try:
registerVirtualServer(self.hostName, self.port, newVirtualServerId)
except faults.RoleNotInProfiles:
return
if self.hasMultipleVirtualServers: if self.hasMultipleVirtualServers:
self.virtualServers[newVirtualServerId] = self.loadVirtualServer( self.virtualServers[newVirtualServerId] = self.loadVirtualServer(
newVirtualServerId) newVirtualServerId)
@ -771,7 +765,6 @@ class Server(things.BaseThing, applications.Application):
context.getVar('applicationTokens')[newVirtualServerId] = \ context.getVar('applicationTokens')[newVirtualServerId] = \
getApplicationToken() getApplicationToken()
context.pull() context.pull()
registerVirtualServer(self.hostName, self.port, newVirtualServerId)
def canGetAdmin(self): def canGetAdmin(self):
"""Indicate whether the caller is able to get the admin instance. """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: if self.port is not None:
del self.port 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: if self.useDataFile:
self.dataDirectoryPath = commonTools.getConfig( self.dataDirectoryPath = commonTools.getConfig(
'Misc', 'DataDirectoryPath') 'Misc', 'DataDirectoryPath')
@ -1317,14 +1302,14 @@ class Server(things.BaseThing, applications.Application):
# Register each virtual server to the dispatcher. # Register each virtual server to the dispatcher.
if self.hasMultipleVirtualServers: if self.hasMultipleVirtualServers:
if self.onlyForDispatcherIds:
dispatcherIds = [
dispatcherId
for dispatcherId in self.onlyForDispatcherIds
if dispatcherId and dispatcherId in dispatcherIds]
for dispatcherId in dispatcherIds: for dispatcherId in dispatcherIds:
virtualServerId = commonTools.makeApplicationId( virtualServerId = commonTools.makeApplicationId(
dispatcherId, self.applicationRole) dispatcherId, self.applicationRole)
try:
registerVirtualServer(
self.hostName, self.port, virtualServerId)
except faults.RoleNotInProfiles:
continue
self.virtualServers[virtualServerId] = self.loadVirtualServer( self.virtualServers[virtualServerId] = self.loadVirtualServer(
virtualServerId) virtualServerId)
context.push( context.push(
@ -1333,8 +1318,6 @@ class Server(things.BaseThing, applications.Application):
context.getVar('applicationTokens')[virtualServerId] = \ context.getVar('applicationTokens')[virtualServerId] = \
getApplicationToken() getApplicationToken()
context.pull() context.pull()
registerVirtualServer(
self.hostName, self.port, virtualServerId)
def removeIdsFromVirtualServer(self, dispatcherId, rolesToKeep): def removeIdsFromVirtualServer(self, dispatcherId, rolesToKeep):
virtualServerId = commonTools.makeApplicationId( virtualServerId = commonTools.makeApplicationId(

View File

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

View File

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

View File

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

View File

@ -66,10 +66,6 @@ class Comment(ObjectWebMixin, Comment):
body_kind_widget_rows = 20 body_kind_widget_rows = 20
body_kind_widgetName = 'TextArea' 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): def getEditLayoutSlotNames(self, fields, parentSlot = None):
slotNames = ObjectWebMixin.getEditLayoutSlotNames(self, fields, slotNames = ObjectWebMixin.getEditLayoutSlotNames(self, fields,
parentSlot = parentSlot) [:] parentSlot = parentSlot) [:]
@ -79,23 +75,28 @@ class Comment(ObjectWebMixin, Comment):
slotNames.remove('parentId') slotNames.remove('parentId')
if 'creationTime' in slotNames: if 'creationTime' in slotNames:
slotNames.remove('creationTime') slotNames.remove('creationTime')
if 'isEditorial' in slotNames:
if not self.getWeb().canPostEditorialComment(self.parentId):
slotNames.remove('isEditorial')
pass
return slotNames return slotNames
def getViewLayoutSlotNames(self, fields, parentSlot = None): def getViewLayoutSlotNames(self, fields, parentSlot = None):
return ['title', 'body'] return ['authorId', 'creationTime', 'body']
def getViewLayout(self, fields, parentSlot = None): def getViewLayout(self, fields, parentSlot = None):
sectionLevel = context.getVar('sectionLevel') sectionLevel = context.getVar('sectionLevel')
context.push(sectionLevel = sectionLevel+1) context.push(sectionLevel = sectionLevel+1)
layout = X.array() layout = X.array()
titleSlot = self.getSlot('title') #titleSlot = self.getSlot('title')
titleHtml = titleSlot.getWidget().getHtmlValue(titleSlot, fields) #titleHtml = titleSlot.getWidget().getHtmlValue(titleSlot, fields)
titleTag = getattr(X, 'h%s' % (sectionLevel+1)) #titleTag = getattr(X, 'h%s' % (sectionLevel+1))
if len(titleHtml.children) == 2: #if len(titleHtml.children) == 2:
# remove translation bar # # remove translation bar
del titleHtml.children[1] # del titleHtml.children[1]
layout += titleTag(titleHtml) #layout += titleTag(titleHtml)
authorIdSlot = self.getSlot('authorId') authorIdSlot = self.getSlot('authorId')
if authorIdSlot.getValue(): if authorIdSlot.getValue():
@ -130,6 +131,46 @@ class CommentsWeb(ObjectsWebMixin, CommentsProxy):
def use(self): pass def use(self): pass
def view(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): def viewAll(self):
layout = X.array() layout = X.array()
userToken = context.getVar('userToken') userToken = context.getVar('userToken')

View File

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

View File

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

View File

@ -302,7 +302,7 @@ class ObjectsWebMixin(AdministrableWebMixin):
return pageNotFound() return pageNotFound()
delete.isPublicForWeb = 1 delete.isPublicForWeb = 1
def download(self, id, path): def download(self, id, filename = '', path = 'self'):
localId = commonTools.extractLocalId(id) localId = commonTools.extractLocalId(id)
if localId == '__admin__': if localId == '__admin__':
if not self.canGetAdmin(): if not self.canGetAdmin():
@ -324,6 +324,10 @@ class ObjectsWebMixin(AdministrableWebMixin):
dataFileName = upload.getSlot( dataFileName = upload.getSlot(
'dataFileName', parentSlot = uploadSlot).getValue() 'dataFileName', parentSlot = uploadSlot).getValue()
if dataFileName: if dataFileName:
if not filename:
uri = X.idUrl(id, 'download/%s' % dataFileName).add(
'path', path)
return redirect(uri)
req.headers_out['Content-Disposition'] = \ req.headers_out['Content-Disposition'] = \
'inline; filename="%s"' % dataFileName 'inline; filename="%s"' % dataFileName
req.headers_out['Content-Length'] = str(len(data)) req.headers_out['Content-Length'] = str(len(data))
@ -611,6 +615,10 @@ class ObjectsWebMixin(AdministrableWebMixin):
return None return None
def getViewBelowButtonsBarLayout(self, object, fields): def getViewBelowButtonsBarLayout(self, object, fields):
if hasattr(self, 'addComment') and \
'comments' in context.getVar('knownRoles'):
return getWebForServerRole(
'comments').getBothCommentsLayout(object.id)
return None return None
def getViewButtonsBarLayout(self, object, fields): def getViewButtonsBarLayout(self, object, fields):
@ -1143,6 +1151,7 @@ class CommentableObjectMixin(things.ThingMixin):
def addCommentObject(self, id, object): def addCommentObject(self, id, object):
webRole = getWebForServerRole('comments') webRole = getWebForServerRole('comments')
object.parentId = id
context.push(_level = 'edit', layoutMode = 'edit') context.push(_level = 'edit', layoutMode = 'edit')
try: try:
layout = X.array() layout = X.array()
@ -1182,56 +1191,6 @@ class CommentableObjectMixin(things.ThingMixin):
if context.getVar('debug'): if context.getVar('debug'):
raise raise
return accessForbidden() return accessForbidden()
return redirect(X.idUrl(id, 'withComments')) return redirect(X.idUrl(id))
addCommentSubmit.isPublicForWeb = 1 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: if fileName and object.dataFileName != fileName:
pageNotFound() pageNotFound()
if not fileName and object.dataFileName:
uri = X.idUrl(id, 'download/%s' % object.dataFileName)
return redirect(uri)
req = context.getVar('req') req = context.getVar('req')
req.depends.append(id) req.depends.append(id)

View File

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

View File

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

View File

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

View File

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

View File

@ -26,7 +26,7 @@
</div> </div>
--> -->
<h1><a href="/" tal:reroot="href"><img tal:reroot="src" src="/images/logo-entrouvert.be.png" alt="entrouvert.be" /></a> <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> </h1>
</div> </div>

View File

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

View File

@ -273,3 +273,10 @@ td.translation-ok, td.translation-missing {
text-align: center; 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' glasnostPythonDir = '/usr/local/lib/glasnost-tests'
sys.path.insert(0, glasnostPythonDir) sys.path.insert(0, glasnostPythonDir)
import glasnost.common.context as context
from glasnost.common.parsers import makeHtmlFromSpip from glasnost.common.parsers import makeHtmlFromSpip
class SpipParserTestCase(unittest.TestCase): class SpipParserTestCase(unittest.TestCase):
def setUp(self):
context.push(dispatcherId = 'glasnost://localhost')
def test00_plainSentence(self): def test00_plainSentence(self):
'''Render a plain sentence''' '''Render a plain sentence'''
result = makeHtmlFromSpip('''this is not interesting''') result = makeHtmlFromSpip('''this is not interesting''')
@ -37,12 +41,12 @@ class SpipParserTestCase(unittest.TestCase):
def test05_glasnostLink(self): def test05_glasnostLink(self):
'''Render a link to a Glasnost article''' '''Render a link to a Glasnost article'''
result = makeHtmlFromSpip('''[->article 2]''', inline = 1) 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): def test06_glasnostPageNameLink(self):
'''Render a link using an alias''' '''Render a link using an alias'''
result = makeHtmlFromSpip('''[->alias test]''', inline = 1) 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): def test07_nothingSpecialLink(self):
'''Render a plain link, nothing special''' '''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': if attrs.has_key('type') and attrs['type'] == 'submit':
self.currentForm.buttons.append( (attrs['name'], attrs['value']) ) self.currentForm.buttons.append( (attrs['name'], attrs['value']) )
return 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 self.currentForm.values[attrs['name']] = None
if attrs.has_key('value'): if attrs.has_key('value'):
self.currentForm.values[attrs['name']] = attrs['value'] self.currentForm.values[attrs['name']] = attrs['value']