- 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:
parent
38cb449f59
commit
ac17ad0fe7
24
Makefile
24
Makefile
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -0,0 +1,2 @@
|
||||||
|
*.xml
|
||||||
|
*.xml.in.h
|
|
@ -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>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<glasnost>
|
||||||
|
<_description>Cards Support</_description>
|
||||||
|
<roles>
|
||||||
|
<role>cards</role>
|
||||||
|
</roles>
|
||||||
|
</glasnost>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<glasnost>
|
||||||
|
<_description>Comments Support</_description>
|
||||||
|
<roles>
|
||||||
|
<role>comments</role>
|
||||||
|
</roles>
|
||||||
|
</glasnost>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<glasnost>
|
||||||
|
<_description>LDAP Support</_description>
|
||||||
|
<roles>
|
||||||
|
<role>authentication-ldap</role>
|
||||||
|
<role>ldappeople</role>
|
||||||
|
</roles>
|
||||||
|
</glasnost>
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<glasnost>
|
||||||
|
<_description>Translations Support</_description>
|
||||||
|
<roles>
|
||||||
|
<role>translations</role>
|
||||||
|
</roles>
|
||||||
|
</glasnost>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)' % (
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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'
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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*:
|
||||||
|
|
|
@ -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*:
|
||||||
|
|
|
@ -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*:
|
||||||
|
|
|
@ -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('&', '&') # ?
|
'&', '&').replace(
|
||||||
s = s.replace('"', '"') # '"' must be converted.
|
'"', '"').replace(
|
||||||
s = s.replace('<', '<') # ?
|
'\'', ''').replace(
|
||||||
s = s.replace('>', '>') # ?
|
'<', '<').replace(
|
||||||
return s
|
'>', '>')
|
||||||
|
|
||||||
|
|
||||||
def enclose(object, **enclosingAttributes):
|
def enclose(object, **enclosingAttributes):
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 = {}
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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 = '')
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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')
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
*.htmlc.*
|
||||||
|
*.talc.*
|
||||||
|
infos.xml
|
||||||
|
infos.xml.in.h
|
|
@ -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'''
|
||||||
|
|
|
@ -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']
|
||||||
|
|
Reference in New Issue