Changed everything (even the application name).

This commit is contained in:
eraviart 2004-03-31 07:53:26 +00:00
parent b18a933c6c
commit 5f631d0b2d
143 changed files with 3848 additions and 2385 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<configuration schema="/schemas/Configuration.xsd"
xmlns="http://abracadabra.entrouvert.org/0.0">
<logFilePath>/tmp/glasnost-xml.log</logFilePath>
<pidFilePath>glasnost-xml.pid</pidFilePath>
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<logFilePath>/var/log/expression.log</logFilePath>
<pidFilePath>expression.pid</pidFilePath>
<adminEmail>webmaster@localhost</adminEmail>
<!--
<user>www-data</user>
@ -11,36 +11,36 @@
<module>
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>bug</name>
<schema>/schemas/Bug.xsd</schema>
<description>/descriptions/Bug.xml</description>
</object>
</module>
<module name="abracadabra.descriptions"/>
<module name="abracadabra.groups"/>
<module name="abracadabra.xhtml2"/>
<module name="abracadabra.identities"/>
<module name="abracadabra.pagesequences"/>
<module name="abracadabra.persons">
<module name="expression.descriptions"/>
<module name="expression.groups"/>
<module name="expression.xhtml2"/>
<module name="expression.identities"/>
<module name="expression.pagesequences"/>
<module name="expression.persons">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>person</name>
<schema>/schemas/Person.xsd</schema>
<description>/descriptions/Person.xml</description>
</object>
</module>
<module name="abracadabra.passwordaccounts">
<module name="expression.passwordaccounts">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>passwordAccounts</name>
<schema>/schemas/PasswordAccount.xsd</schema>
<description>/descriptions/PasswordAccount.xml</description>
</object>
</module>
<module name="abracadabra.sessions"/>
<module name="abracadabra.xforms"/>
<module name="abracadabra.xmlschemas"/>
<module name="expression.sessions"/>
<module name="expression.xforms"/>
<module name="expression.xmlschemas"/>
<virtualHost ip="*" port="1997">
<serverName>localhost</serverName>

View File

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<configuration schema="/schemas/Configuration.xsd"
xmlns="http://abracadabra.entrouvert.org/0.0">
<logFilePath>/var/log/glasnost-xml.log</logFilePath>
<pidFilePath>glasnost-xml.pid</pidFilePath>
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<logFilePath>/var/log/expression.log</logFilePath>
<pidFilePath>expression.pid</pidFilePath>
<adminEmail>webmaster@localhost</adminEmail>
<!--
<user>www-data</user>
@ -11,44 +11,44 @@
<module>
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>article</name>
<schema>/schemas/Article.xsd</schema>
<description>/descriptions/Article.xml</description>
</object>
</module>
<module name="abracadabra.descriptions"/>
<module name="abracadabra.elections"/>
<module name="abracadabra.fichesLiaison">
<module name="expression.descriptions"/>
<module name="expression.elections"/>
<module name="expression.fichesLiaison">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>ficheLiaison</name>
<schema>/schemas/FicheLiaison.xsd</schema>
<description>/descriptions/FicheLiaison.xml</description>
</object>
</module>
<module name="abracadabra.groups"/>
<module name="abracadabra.identities">
<module name="expression.groups"/>
<module name="expression.identities">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>identity</name>
<schema>/schemas/Identity.xsd</schema>
<description>/descriptions/Identity.xml</description>
</object>
</module>
<module name="abracadabra.libertyalliance"/>
<module name="abracadabra.pagesequences"/>
<module name="abracadabra.persons">
<module name="expression.libertyalliance"/>
<module name="expression.pagesequences"/>
<module name="expression.persons">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>person</name>
<schema>/schemas/Person.xsd</schema>
<description>/descriptions/Person.xml</description>
</object>
</module>
<module name="abracadabra.sessions"/>
<module name="abracadabra.xforms"/>
<module name="abracadabra.xmlschemas"/>
<module name="expression.sessions"/>
<module name="expression.xforms"/>
<module name="expression.xmlschemas"/>
<virtualHost ip="*" port="80">
<serverName>formulaires</serverName>

View File

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<configuration schema="/schemas/Configuration.xsd"
xmlns="http://abracadabra.entrouvert.org/0.0">
<logFilePath>/var/log/glasnost-xml.log</logFilePath>
<pidFilePath>glasnost-xml.pid</pidFilePath>
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<logFilePath>/var/log/expression.log</logFilePath>
<pidFilePath>expression.pid</pidFilePath>
<adminEmail>webmaster@localhost</adminEmail>
<!--
<user>www-data</user>
@ -11,69 +11,69 @@
<module>
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>article</name>
<schema>/schemas/Article.xsd</schema>
<description>/descriptions/Article.xml</description>
</object>
</module>
<module name="abracadabra.ballotboxes">
<module name="expression.ballotboxes">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>ballotBox</name>
<schema>/schemas/BallotBox.xsd</schema>
<description>/descriptions/BallotBox.xml</description>
</object>
</module>
<module name="abracadabra.descriptions"/>
<module name="abracadabra.elections"/>
<module name="abracadabra.groups"/>
<module name="abracadabra.identities"/>
<module name="abracadabra.inscriptions">
<module name="expression.descriptions"/>
<module name="expression.elections"/>
<module name="expression.groups"/>
<module name="expression.identities"/>
<module name="expression.inscriptions">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>inscription</name>
<schema>/schemas/Inscription.xsd</schema>
<description>/descriptions/Inscription.xml</description>
</object>
</module>
<module name="abracadabra.libertyalliance"/>
<module name="abracadabra.pagesequences"/>
<module name="abracadabra.persons">
<module name="expression.libertyalliance"/>
<module name="expression.pagesequences"/>
<module name="expression.persons">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>person</name>
<schema>/schemas/Person.xsd</schema>
<description>/descriptions/Person.xml</description>
</object>
</module>
<module name="abracadabra.questionnaires">
<module name="expression.questionnaires">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>questionnaire</name>
<schema>/schemas/Questionnaire.xsd</schema>
<description>/descriptions/Questionnaire.xml</description>
</object>
</module>
<module name="abracadabra.passwordaccounts">
<module name="expression.passwordaccounts">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>passwordAccounts</name>
<schema>/schemas/PasswordAccount.xsd</schema>
<description>/descriptions/PasswordAccount.xml</description>
</object>
</module>
<module name="abracadabra.sessions"/>
<module name="abracadabra.votes">
<module name="expression.sessions"/>
<module name="expression.votes">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>vote</name>
<schema>/schemas/Vote.xsd</schema>
<description>/descriptions/Vote.xml</description>
</object>
</module>
<module name="abracadabra.xforms"/>
<module name="abracadabra.xmlschemas"/>
<module name="expression.xforms"/>
<module name="expression.xmlschemas"/>
<virtualHost ip="*" port="1997">
<serverName>localhost</serverName>

View File

@ -1,20 +1,21 @@
<?xml version="1.0"?>
<configuration schema="/schemas/Configuration.xsd"
xmlns="http://abracadabra.entrouvert.org/0.0">
<logFilePath>/tmp/glasnost-xml.log</logFilePath>
<pidFilePath>glasnost-xml.pid</pidFilePath>
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<logFilePath>/var/log/expression.log</logFilePath>
<pidFilePath>expression.pid</pidFilePath>
<adminEmail>webmaster@localhost</adminEmail>
<!--
<user>www-data</user>
<group>www-data</group>
-->
<module name="abracadabra.descriptions"/>
<module name="abracadabra.pagesequences"/>
<module name="abracadabra.sessions"/>
<module name="abracadabra.xforms"/>
<module name="abracadabra.xmlschemas"/>
<module name="abracadabra.xhtml2"/>
<module name="expression.descriptions"/>
<module name="expression.groups"/>
<module name="expression.pagesequences"/>
<module name="expression.sessions"/>
<module name="expression.xforms"/>
<module name="expression.xmlschemas"/>
<module name="expression.xhtml2"/>
<virtualHost ip="*" port="1997">
<serverName>localhost</serverName>

View File

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<configuration schema="/schemas/Configuration.xsd"
xmlns="http://abracadabra.entrouvert.org/0.0">
<logFilePath>/var/log/glasnost-xml.log</logFilePath>
<pidFilePath>glasnost-xml.pid</pidFilePath>
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<logFilePath>/var/log/expression.log</logFilePath>
<pidFilePath>expression.pid</pidFilePath>
<adminEmail>webmaster@localhost</adminEmail>
<!--
<user>www-data</user>
@ -11,52 +11,52 @@
<module>
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>article</name>
<schema>/schemas/Article.xsd</schema>
<description>/descriptions/Article.xml</description>
</object>
</module>
<module name="abracadabra.ballotboxes">
<module name="expression.ballotboxes">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>ballotBox</name>
<schema>/schemas/BallotBox.xsd</schema>
<description>/descriptions/BallotBox.xml</description>
</object>
</module>
<module name="abracadabra.descriptions"/>
<module name="abracadabra.elections"/>
<module name="abracadabra.groups"/>
<module name="abracadabra.identities">
<module name="expression.descriptions"/>
<module name="expression.elections"/>
<module name="expression.groups"/>
<module name="expression.identities">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>identity</name>
<schema>/schemas/Identity.xsd</schema>
<description>/descriptions/Identity.xml</description>
</object>
</module>
<module name="abracadabra.libertyalliance"/>
<module name="abracadabra.pagesequences"/>
<module name="abracadabra.persons">
<module name="expression.libertyalliance"/>
<module name="expression.pagesequences"/>
<module name="expression.persons">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>person</name>
<schema>/schemas/Person.xsd</schema>
<description>/descriptions/Person.xml</description>
</object>
</module>
<module name="abracadabra.sessions"/>
<module name="abracadabra.votes">
<module name="expression.sessions"/>
<module name="expression.votes">
<object>
<namespace>http://abracadabra.entrouvert.org/0.0</namespace>
<namespace>http://www.entrouvert.org/namespaces/expression/0.0</namespace>
<name>vote</name>
<schema>/schemas/Vote.xsd</schema>
<description>/descriptions/Vote.xml</description>
</object>
</module>
<module name="abracadabra.xforms"/>
<module name="abracadabra.xmlschemas"/>
<module name="expression.xforms"/>
<module name="expression.xmlschemas"/>
<virtualHost ip="*" port="1997">
<serverName>localhost</serverName>

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -23,22 +22,22 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Glasnost-XML Shared Modules"""
"""Expression Shared Modules"""
__version__ = '$Revision$'[11:-2]
__version__ = "$Revision$"[11:-2]
applicationName = 'glasnost-xml' # Changed on "make install".
versionNumber = '(Unreleased CVS Version)' # Changed on "make install".
applicationName = "expression" # Changed on "make install".
versionNumber = "(Unreleased CVS Version)" # Changed on "make install".
import __builtin__
__builtin__.__dict__['N_'] = lambda x: x
__builtin__.__dict__['_'] = lambda x: x
__builtin__.__dict__["N_"] = lambda x: x
__builtin__.__dict__["_"] = lambda x: x
# Shall be located before the other Abracadabra imports.
# Shall be located before the other Expression imports.
import environs
environs.clear()
environs.push()

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -69,52 +68,55 @@ class ActionHandlerMixin(object):
administrators = self.administrators
return administrators is not None and administrators.containsUser()
def output(self):
def outputHtml(self):
raise NotImplementedError
def walk(self, httpNames):
if httpNames == ["exits"]:
return True
elif httpNames == ["isAuthorized"]:
return self.modeAccessIsAuthorized("access")
else:
if not self.modeAccessIsAuthorized("access"):
raise faults.PathUnauthorized("/".join(httpNames))
if not httpNames:
return self
environs.push(
_level = "walk",
currentActionHandler = self,
pageName = None)
try:
return self.walk1(httpNames)
finally:
environs.pull(_level = "walk")
def outputSource(self):
raise NotImplementedError
def walk1(self, httpNames):
return self.walkActions(httpNames)
#~ def walk(self, httpNames):
#~ if httpNames == ["exits"]:
#~ return True
#~ elif httpNames == ["isAuthorized"]:
#~ return self.modeAccessIsAuthorized("access")
#~ else:
#~ if not self.modeAccessIsAuthorized("access"):
#~ raise faults.PathUnauthorized("/".join(httpNames))
#~ if not httpNames:
#~ return self
#~ environs.push(
#~ _level = "walk",
#~ currentActionHandler = self,
#~ pageName = None)
#~ try:
#~ return self.walk1(httpNames)
#~ finally:
#~ environs.pull(_level = "walk")
def walkActions(self, httpNames):
if not httpNames:
return self
return self.walkActions1(httpNames)
#~ def walk1(self, httpNames):
#~ return self.walkActions(httpNames)
def walkActions1(self, httpNames):
name = httpNames[0]
remainingNames = httpNames[1:]
if name in ("doHttpRequest", "exists", "isAuthorized"):
pageName = environs.getVar("pageName")
if pageName is None:
pageName = "view"
return self.do(pageName, httpNames, self.output)
elif name == "source":
return self.do(name, httpNames[1:], self.dataHolder.outputSource)
elif name in self.submitActionNames and hasattr(self, name):
return self.do(name, httpNames[1:], getattr(self, name))
elif httpNames[-1] == "exists":
return False
else:
raise faults.PathNotFound("/".join(httpNames))
#~ def walkActions(self, httpNames):
#~ if not httpNames:
#~ return self
#~ return self.walkActions1(httpNames)
#~ def walkActions1(self, httpNames):
#~ name = httpNames[0]
#~ remainingNames = httpNames[1:]
#~ if name in ("doHttpRequest", "exists", "isAuthorized"):
#~ pageName = environs.getVar("pageName")
#~ if pageName is None:
#~ pageName = "view"
#~ return self.do(pageName, httpNames, self.outputHtml)
#~ elif name == "source":
#~ return self.do(name, httpNames[1:], self.outputSource)
#~ elif name in self.submitActionNames and hasattr(self, name):
#~ return self.do(name, httpNames[1:], getattr(self, name))
#~ elif httpNames[-1] == "exists":
#~ return False
#~ else:
#~ raise faults.PathNotFound("/".join(httpNames))
actionHandler = property(getActionHandler)
administrators = property(getAdministrators)

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -26,11 +25,11 @@
"""Ballot Boxes Module"""
import dataholders
import directories
import environs
import modules
import namespaces
import stations
class BallotBox(directories.Directory):
@ -42,8 +41,7 @@ class BallotBox(directories.Directory):
if voteToken is None:
vote = None
else:
vote = dataholders.walkToLocation(
self.getSubPathInternUri(voteToken))
vote = self.walkToLocation(self.getSubPathInternUri(voteToken))
if vote is None:
vote = newVote(self, temporary = True)
return vote

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -28,19 +27,19 @@
import libxml2
import dataholders
import elements
import html
import modules
import namespaces
import parsers
import stations
class Election(elements.Element):
def fillResult1FieldValueLayout(self, description, layout):
ballotBox = dataholders.walkToLocation(self.ballotBoxLocation)
ballotBox = self.walkToLocation(self.ballotBoxLocation)
formDescriptionLocation = "/descriptions/Form1.xml"
formDescription = dataholders.walkToLocation(formDescriptionLocation)
formDescription = self.walkToLocation(formDescriptionLocation)
votePageNodes = formDescription.evaluateXpath(
"yep:page[starts-with(@name, 'question')]")
votePageNames = {}

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -37,6 +36,7 @@ import logs
import modules
import namespaces
import sessions
import stations
import strings
@ -163,7 +163,7 @@ class Inscription(elements.Element):
if environs.getVar("debug"):
raise Exception(
"""Description "%s" missing""" % self.descriptionLocation)
raise faults.PathNotFound(dataHolder.uriInternPath)
raise faults.PathNotFound(self.uriInternPath)
description.submit()
alerts = {}
if not self.connaissanceReglement:
@ -181,7 +181,7 @@ class Inscription(elements.Element):
if not self.nomCorrespondant:
alerts["yep_nomCorrespondant"] = "Valeur manquante"
if not "yep_courriel" in alerts:
inscriptionExists = dataholders.walkToLocation(
inscriptionExists = self.walkToLocation(
"/inscriptions/%s/exists" % strings.simplify(self.courriel))
if dataHolder.localId.startswith("new-") and inscriptionExists:
alerts["yep_courriel"] = "Adresse courriel déjà utilisée"
@ -341,12 +341,12 @@ L'équipe Villes Internet
finally:
environs.pull(_level = "submitToUrl")
return
# dataHolder.save() done below
# dataHolder.save() is done below
session = environs.getVar("session")
session.authenticationMethod = "password"
session.userLocation = dataHolder.uriInternPath
self.sessionLocation = session.dataHolder.uriInternPath
session.userLocation = self.uriInternPath
self.sessionLocation = session.uriInternPath
dataHolder.save()
baseEnviron = environs.get(_level = "handleHttpCommand")
baseEnviron.setVar("user", self)

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -26,7 +25,6 @@
"""Page Sequences (aka Slideshows) Module"""
import dataholders
import elements
import environs
import html
@ -34,6 +32,7 @@ import locations
import logs
import modules
import namespaces
import stations
class PageSequence(elements.Element):
@ -52,9 +51,9 @@ class PageSequence(elements.Element):
return False
pageNode = pageNodes[0]
pageLocation = self.evaluateXpath("@src", pageNode)[0].content
page = dataholders.walkToLocation(pageLocation)
page = self.walkToLocation(pageLocation)
environs.push(_level = "PageSequence.fillPageLayout",
currentActionHandler = page)
currentStation = page)
try:
inForm = page.layoutRequiresForm()
finally:
@ -68,9 +67,10 @@ class PageSequence(elements.Element):
if not environs.getVar("canUseCookie"):
session = environs.getVar("session")
if session is not None:
sessionHolder = session.dataHolder
pageLayout.append(html.input(
name = "sessionToken", type = "hidden",
value = session.dataHolder.localId))
value = sessionHolder.localId))
pageLayout.append(html.input(
name = "pageNumber", type = "hidden",
value = str(pageNumber)))
@ -78,7 +78,7 @@ class PageSequence(elements.Element):
pageLayout = layout
environs.push(_level = "PageSequence.fillPageLayout",
currentActionHandler = page)
currentStation = page)
try:
page.fillPageBodyLayout(pageLayout, inForm = inForm)
finally:
@ -161,13 +161,13 @@ class PageSequence(elements.Element):
pageNode = pageNodes[0]
pageLocation = self.evaluateXpath("@src", pageNode)[0].content
# FIXME.
page, splitedAction = dataholders.walkToLocation(pageLocation)
page, splitedAction = self.walkToLocation(pageLocation)
if splitedAction:
pageName = splitedAction[0]
else:
pageName = None
environs.push(_level = "PageSequence.submit",
currentActionHandler = page,
currentStation = page,
pageName = pageName)
try:
return page.submitToUrl(dataHolder.getActionUri(
@ -177,43 +177,43 @@ class PageSequence(elements.Element):
raise faults.PathNotFound("/".join(arguments))
return elements.Element.submit(self, *arguments)
def walkActions1(self, httpNames):
name = httpNames[0]
remainingNames = httpNames
if name == 'doHttpRequest':
pageNumber = 1
elif name.isdigit():
pageNumber = int(name)
remainingNames = remainingNames[1:]
else:
pageNumber = None
if pageNumber is not None:
dataHolder = self.dataHolder
pageNodes = self.evaluateXpath('yep:pages/*[%d]' % pageNumber)
if not pageNodes:
if httpNames[-1] == 'exists':
return False
else:
raise faults.PathNotFound('/'.join(httpNames))
pageNode = pageNodes[0]
if pageNode.name == 'login':
libertyAlliance = dataholders.walkToLocation(
'/liberty-alliance')
return libertyAlliance.do(
'view', remainingNames, libertyAlliance.loginToUrl,
dataHolder.getActionUri('%d' % (pageNumber + 1)))
elif pageNode.name == 'logout':
libertyAlliance = dataholders.walkToLocation(
'/liberty-alliance')
return libertyAlliance.do(
'view', remainingNames, libertyAlliance.logoutToUrl,
dataHolder.getActionUri('%d' % (pageNumber + 1)))
else:
#~ def walkActions1(self, httpNames):
#~ name = httpNames[0]
#~ remainingNames = httpNames
#~ if name == 'doHttpRequest':
#~ pageNumber = 1
#~ elif name.isdigit():
#~ pageNumber = int(name)
#~ remainingNames = remainingNames[1:]
#~ else:
#~ pageNumber = None
#~ if pageNumber is not None:
#~ dataHolder = self.dataHolder
#~ pageNodes = self.evaluateXpath('yep:pages/*[%d]' % pageNumber)
#~ if not pageNodes:
#~ if httpNames[-1] == 'exists':
#~ return False
#~ else:
#~ raise faults.PathNotFound('/'.join(httpNames))
#~ pageNode = pageNodes[0]
#~ if pageNode.name == 'login':
#~ libertyAlliance = self.walkToLocation(
#~ '/liberty-alliance')
#~ return libertyAlliance.do(
#~ 'view', remainingNames, libertyAlliance.loginToUrl,
#~ dataHolder.getActionUri('%d' % (pageNumber + 1)))
#~ elif pageNode.name == 'logout':
#~ libertyAlliance = self.walkToLocation(
#~ '/liberty-alliance')
#~ return libertyAlliance.do(
#~ 'view', remainingNames, libertyAlliance.logoutToUrl,
#~ dataHolder.getActionUri('%d' % (pageNumber + 1)))
#~ else:
#~ pageLocation = self.evaluateXpath("@src", pageNode)[0].content
#~ page = dataholders.walkToLocation(pageLocation)
#~ page = self.walkToLocation(pageLocation)
#~ return page.walk(remainingNames)
return self.do('view', remainingNames, self.output)
return elements.Element.walkActions1(self, httpNames)
#~ return self.do('view', remainingNames, self.output)
#~ return elements.Element.walkActions1(self, httpNames)
title = property(getTitle)
simpleLabel = property(getSimpleLabel)

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -37,49 +36,50 @@ import environs
import faults
import modules
import namespaces
import resources
import stations
import strings
class MyQuestionnaire(elements.Element):
def walk1(self, httpNames):
user = environs.getVar("user")
if user is None:
if httpNames[-1] == 'exists':
return False
raise faults.PathUnauthorized("/".join(httpNames))
try:
questionnaire = dataholders.walkToLocation(
"/questionnaires/%s" % strings.simplify(user.email))
except faults.PathNotFound:
try:
constructor = modules.getHolderConstructor(
namespaces.yep.uri, "questionnaire")
except KeyError:
if httpNames[-1] == 'exists':
return False
raise faults.PathNotFound('/'.join(httpNames))
questionnaires = dataholders.walkToLocation("/questionnaires/")
questionnaireHolder = constructor(questionnaires)
else:
questionnaireHolder = questionnaire.dataHolder
# Recreate a new holder for the questionnaire, with the same file path,
# but the uri of myQuestionnaire.
newUriStep = copy.copy(self.dataHolder.resource.uriStep)
newUriStep.resource = None
newFileSystemStep = copy.copy(
questionnaireHolder.resource.fileSystemStep)
newFileSystemStep.resource = None
newFileSystemHierarchicalStep = copy.copy(
questionnaireHolder.resource.fileSystemHierarchicalStep)
newFileSystemHierarchicalStep.resource = None
newResource = resources.LocalResource(
newUriStep, newFileSystemStep, newFileSystemHierarchicalStep)
newHolder = dataholders.XmlHolder(newResource)
newHolder.doc = questionnaireHolder.doc
newHolder.isTemporary = True
newHolder.setupDataHolder()
return newHolder.walk(httpNames)
pass
#~ def walk1(self, httpNames):
#~ user = environs.getVar("user")
#~ if user is None:
#~ if httpNames[-1] == 'exists':
#~ return False
#~ raise faults.PathUnauthorized("/".join(httpNames))
#~ try:
#~ questionnaire = self.walkToLocation(
#~ "/questionnaires/%s" % strings.simplify(user.email))
#~ except faults.PathNotFound:
#~ try:
#~ constructor = modules.getHolderConstructor(
#~ namespaces.yep.uri, "questionnaire")
#~ except KeyError:
#~ if httpNames[-1] == 'exists':
#~ return False
#~ raise faults.PathNotFound('/'.join(httpNames))
#~ questionnaires = self.walkToLocation("/questionnaires/")
#~ questionnaireHolder = constructor(questionnaires)
#~ else:
#~ questionnaireHolder = questionnaire.dataHolder
#~ # Recreate a new holder for the questionnaire, with the same file path,
#~ # but the uri of myQuestionnaire.
#~ newUriStep = copy.copy(self.dataHolder.resource.uriStep)
#~ newUriStep.resource = None
#~ newFileSystemStep = copy.copy(
#~ questionnaireHolder.resource.fileSystemStep)
#~ newFileSystemStep.resource = None
#~ newFileSystemHierarchicalStep = copy.copy(
#~ questionnaireHolder.resource.fileSystemHierarchicalStep)
#~ newFileSystemHierarchicalStep.resource = None
#~ newResource = resources.LocalResource(
#~ newUriStep, newFileSystemStep, newFileSystemHierarchicalStep)
#~ newHolder = dataholders.XmlHolder(newResource)
#~ newHolder.node = questionnaireHolder.node
#~ newHolder.isTemporary = True
#~ newHolder.setupDataHolder()
#~ return newHolder.walk(httpNames)
class Questionnaire(elements.Element):

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -31,8 +30,8 @@ import elements
import environs
import modules
import namespaces
import resources
import steps
import stations
class Vote(elements.Element):
@ -52,38 +51,36 @@ class VoteHolder(dataholders.XmlHolder):
class Votes(elements.Element):
def walk1(self, httpNames):
if httpNames:
httpName = httpNames[0]
# HttpName is an election local id.
ballotBox = dataholders.walkToLocation("/ballot-boxes/%s" % httpName)
vote = ballotBox.getUserVote()
voteHolder = vote.dataHolder
voteUriStep = steps.UriStep(
self.dataHolder.resource.uriStep, httpName)
dataHolder = dataholders.getCachedDataHolder(
voteUriStep.absoluteUri)
if dataHolder is None:
voteFileSystemStep = voteHolder.resource.fileSystemStep
voteFileSystemStep = steps.FileSystemStep(
voteFileSystemStep.previous, voteFileSystemStep.name)
voteFileSystemHierarchicalStep \
= voteHolder.resource.fileSystemHierarchicalStep
voteFileSystemHierarchicalStep \
= steps.FileSystemHierarchicalStep(
voteFileSystemHierarchicalStep.parent,
voteFileSystemHierarchicalStep.name)
voteResource = resources.LocalResource(
voteUriStep, voteFileSystemStep,
voteFileSystemHierarchicalStep)
doc = voteHolder.doc
voteHolder = dataholders.DataHolder(
voteResource, mimeType = voteHolder.mimeType,
outputMimeType = voteHolder.outputMimeType)
voteHolder.doc = doc.copyDoc(True)
voteHolder.setup()
return voteHolder.walk(httpNames[1:])
return elements.Element.walk1(self, httpNames)
pass
#~ def walk1(self, httpNames):
#~ if httpNames:
#~ httpName = httpNames[0]
#~ # HttpName is an election local id.
#~ ballotBox = self.walkToLocation("/ballot-boxes/%s" % httpName)
#~ vote = ballotBox.getUserVote()
#~ voteHolder = vote.dataHolder
#~ voteUriStep = steps.UriStep(
#~ self.dataHolder.resource.uriStep, httpName)
#~ voteFileSystemStep = voteHolder.resource.fileSystemStep
#~ voteFileSystemStep = steps.FileSystemStep(
#~ voteFileSystemStep.previous, voteFileSystemStep.name)
#~ voteFileSystemHierarchicalStep \
#~ = voteHolder.resource.fileSystemHierarchicalStep
#~ voteFileSystemHierarchicalStep \
#~ = steps.FileSystemHierarchicalStep(
#~ voteFileSystemHierarchicalStep.parent,
#~ voteFileSystemHierarchicalStep.name)
#~ voteResource = resources.LocalResource(
#~ voteUriStep, voteFileSystemStep,
#~ voteFileSystemHierarchicalStep)
#~ node = voteHolder.node
#~ voteHolder = dataholders.DataHolder(
#~ voteResource, mimeType = voteHolder.mimeType,
#~ outputMimeType = voteHolder.outputMimeType)
#~ voteHolder.node = node.copyDoc(True)
#~ voteHolder.setup()
#~ return voteHolder.walk(httpNames[1:])
#~ return elements.Element.walk1(self, httpNames)
modules.registerElementClass(namespaces.yep.uri, "vote", Vote)

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -48,10 +47,14 @@ class Element(elements.Element):
if not nodes:
return False
self.dataHolder.sectionLevel = 0
self.generateChildrenHtml(layout, nodes)
# FIXME: Create implementation
self.generateChildrenHtml(implementation, layout, nodes)
return True
def generateChildrenHtml(self, layout, nodes):
def generateHtml(self, layout):
return self.generateHtmlImplementation(self, layout)
def generateChildrenHtml(self, implementation, layout, nodes):
for childNode in nodes:
if childNode.type == "text":
layout.append(childNode.content)
@ -60,45 +63,70 @@ class Element(elements.Element):
elementClass = modules.getElementClass(
childNode.ns().content, childNode.name)
element = elementClass(childNode, self.dataHolder)
element.generateHtml(layout)
element.generateHtmlImplementation(implementation, layout)
childNode = childNode.next
class WidgetElement(widgets.WidgetMixin, Element):
quickMapNodeName = None
def generateHtml(self, layout):
def generateHtmlImplementation(self, implementation, layout):
# By default, for HTML (XHTML1) we use the same element as in XHTML2.
# Only the namespace changes.
node = self.node
nodeName = node.name
if self.quickMapNodeName:
nodeName = self.quickMapNodeName
newNode = libxml2.newNode(nodeName)
layout.append(newNode)
newWidget = elements.newElement(newNode)
newNode = libxml2.newNode(node.name)
attribute = node.properties
while attribute is not None:
if attribute.name == 'href':
newSubNode = libxml2.newNode('a')
newSubNode.newProp('href', attribute.content)
newWidget.append(newSubNode)
newWidget = elements.newElement(newSubNode)
attribute = attribute.next
continue
newNode.newProp(attribute.name, attribute.content)
attribute = attribute.next
#~ newNode.copyPropList(node)
#~ newNode.setNs(None)
layout.append(newNode)
newWidget = elements.newElement(newNode)
childNode = node.children
while childNode is not None:
if childNode.type == "comment":
childNode = childNode.next
continue
if childNode.type == "text":
newWidget.append(childNode.content)
childNode = childNode.next
continue
element = elements.newElement(childNode, parent = self)
element.generateHtml(newWidget)
element = self.newElement(childNode)
element.generateHtmlImplementation(implementation, newWidget)
childNode = childNode.next
return True
#~ def generateHtmlImplementation(self, implementation, layout):
#~ node = self.node
#~ nodeName = node.name
#~ if self.quickMapNodeName:
#~ nodeName = self.quickMapNodeName
#~ newNode = libxml2.newNode(nodeName)
#~ layout.append(newNode)
#~ newWidget = elements.newElement(newNode)
#~ attribute = node.properties
#~ while attribute is not None:
#~ if attribute.name == "href":
#~ newSubNode = libxml2.newNode("a")
#~ newSubNode.newProp("href", attribute.content)
#~ newWidget.append(newSubNode)
#~ newWidget = elements.newElement(newSubNode)
#~ attribute = attribute.next
#~ continue
#~ newNode.newProp(attribute.name, attribute.content)
#~ attribute = attribute.next
newNode.copyPropList(node)
newNode.setNs(None)
#~ childNode = node.children
#~ while childNode is not None:
#~ if childNode.type == "text":
#~ newWidget.append(childNode.content)
#~ childNode = childNode.next
#~ continue
#~ element = self.newElement(childNode)
#~ element.generateHtmlImplementation(implementation, newWidget)
#~ childNode = childNode.next
#~ return True
def isInline(self):
raise NotImplementedError
@ -125,11 +153,7 @@ class Xhtml2Holder(dataholders.XmlHolder):
uri = linkNode.content
if not uri:
continue
linkNode.setContent(locations.getUri(uri))
def outputDocUnstyled(self):
self.convertInternUris()
return dataholders.XmlHolder.outputDocUnstyled(self)
linkNode.setContent(self.constructUri(uri))
class a(InlineLevelElement):
@ -145,9 +169,9 @@ class code(InlineLevelElement):
class h(BlockLevelElement):
def generateHtml(self, layout):
def generateHtmlImplementation(self, implementation, layout):
node = self.node
newNode = libxml2.newNode('h%d' % self.dataHolder.sectionLevel)
newNode = libxml2.newNode("h%d" % self.dataHolder.sectionLevel)
newWidget = elements.newElement(newNode)
layout.append(newWidget)
@ -156,15 +180,16 @@ class h(BlockLevelElement):
while childNode is not None:
nodes.append(childNode)
childNode = childNode.next
self.generateChildrenHtml(newWidget, nodes)
self.generateChildrenHtml(implementation, newWidget, nodes)
class head(Element):
class head(WidgetElement):
pass
class html(Element):
pass
class html(WidgetElement):
def generateHtmlPage(self, layout):
return self.generateHtml(layout)
class li(BlockLevelElement):
@ -172,7 +197,7 @@ class li(BlockLevelElement):
class nl(BlockLevelElement):
quickMapNodeName = 'ul'
quickMapNodeName = "ul"
class p(BlockLevelElement):
@ -180,12 +205,12 @@ class p(BlockLevelElement):
class section(BlockLevelElement):
def generateHtml(self, layout):
def generateHtmlImplementation(self, implementation, layout):
node = self.node
self.dataHolder.sectionLevel += 1
newNode = libxml2.newNode('div')
newNode.newProp('class', 'section-h%s' % self.dataHolder.sectionLevel)
newNode = libxml2.newNode("div")
newNode.newProp("class", "section-h%s" % self.dataHolder.sectionLevel)
newWidget = elements.newElement(newNode)
layout.append(newWidget)
@ -194,12 +219,12 @@ class section(BlockLevelElement):
while childNode is not None:
nodes.append(childNode)
childNode = childNode.next
self.generateChildrenHtml(newWidget, nodes)
self.generateChildrenHtml(implementation, newWidget, nodes)
self.dataHolder.sectionLevel -= 1
class title(Element):
class title(WidgetElement):
pass

View File

@ -2,11 +2,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -24,9 +23,9 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Glasnost-XML: Liberty Alliance enabled web server
"""Expression: Liberty Alliance enabled XML web server
Glasnost-XML is a Python web server mainly dedicated to e-voting, e-forms and
Expression is a Python web server mainly dedicated to e-voting, e-forms and
self publishing. It is based on XML, XSLT, XML Schema, XPath, XForms, XMLSec,
SAML & Liberty Alliance standards.
"""
@ -49,11 +48,11 @@ Topic :: Internet :: WWW/HTTP :: HTTP Servers
docLines = __doc__.split("\n")
setup(name = "Glasnost-XML",
setup(name = "Expression",
version = "0.0.1",
maintainer = "Entr'ouvert",
maintainer_email = "glasnost-devel@lists.labs.libre-entreprise.org",
url = "http://glasnost.entrouvert.org",
maintainer_email = "expression-devel@lists.labs.libre-entreprise.org",
url = "http://www.entrouvert.org/expression",
license = "http://www.fsf.org/licenses/gpl.html",
platforms = ["GNU/Linux"],
description = docLines[0],
@ -61,4 +60,4 @@ setup(name = "Glasnost-XML",
for classifier in classifiers.split("\n")
if classifier],
long_description = "\n".join(docLines[2:]),
py_modules = ["glasnost_xml"])
py_modules = ["expression"])

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -75,7 +74,14 @@ class Configuration(elements.Element):
return None
def getVirtualHosts(self):
return VirtualHosts(self.node, dataHolder = self)
hierarchicalWay = self.hierarchicalWay
if hierarchicalWay is not None:
hierarchicalWay = hierarchicalWay.duplicate()
uriWay = self.uriWay
if uriWay is not None:
uriWay = uriWay.duplicate()
return VirtualHosts(
self.node, self.internalWay.duplicate(), hierarchicalWay, uriWay)
def registerHolderConstructors(self):
objectNodes = self.evaluateXpath("yep:module/yep:object")
@ -132,7 +138,7 @@ class VirtualHost(elements.Element):
if nodes:
return nodes[0].content
else:
return self.dataHolder.adminEmailAddress
return self.dataHolder.rootElement.adminEmailAddress
def getDirectoryPath(self):
nodes = self.evaluateXpath("yep:documentRoot")

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -27,11 +26,11 @@
import os
import time
import libxml2
import libxslt
import actionhandlers
import documents
import elements
import environs
import faults
@ -39,7 +38,7 @@ import locations
import logs
import modules
import namespaces
import resources
import stations
import steps
@ -54,6 +53,7 @@ mimeTypes = {
".js": "text/javascript",
".png": "image/png",
".py": "text/x-python-src",
".txt": "text/plain",
".xml": "text/xml",
".xsd": "text/xml",
".xsl": "text/xml",
@ -62,109 +62,93 @@ mimeTypes = {
}
class DataHolder(actionhandlers.ActionHandlerMixin, object):
class DataHolder(stations.AbstractStation):
_stylesheet = None
defaultFileNameExtension = None
mimeType = None
outputMimeType = None
resource = None
def __init__(self, resource, mimeType = None, outputMimeType = None):
def __init__(self, internalWay = None, hierarchicalWay = None,
uriWay = None, isRemote = False, remoteUri = None,
mimeType = None):
"""Do not override this method, it won't work. Override method
setupDataHolder instead.
"""
self.resource = resource
assert resource.dataHolder is None
resource.dataHolder = self
stations.AbstractStation.__init__(
self, internalWay = internalWay, hierarchicalWay = hierarchicalWay,
uriWay = uriWay, isRemote = isRemote, remoteUri = remoteUri)
if mimeType is not None:
self.mimeType = mimeType
if outputMimeType is not None:
self.outputMimeType = outputMimeType
def getAbsolutePath(self):
return self.resource.absolutePath
def getAbsoluteUri(self):
return self.resource.absoluteUri
def getActionUri(self, action = None):
uri = self.uriAbsolutePath
if action:
if uri[-1] == "/":
uri = "%s%s" % (uri, action)
else:
uri = "%s/%s" % (uri, action)
if not environs.getVar("canUseCookie"):
session = environs.getVar("session")
if session is not None:
uri = locations.appendParameterToUrl(
uri, "sessionToken", session.dataHolder.localId)
return uri
def getAdministrators(self):
return self.getParentAdministrators()
def getModificationTime(self):
absolutePath = self.absolutePath
if absolutePath is None:
return absolutePath
if os.path.exists(absolutePath):
return time.gmtime(os.stat(absolutePath)[-2])
else:
systemAbsolutePath = self.systemAbsolutePath
return time.gmtime(os.stat(systemAbsolutePath)[-2])
def getParentAdministrators(self):
parent = self.parent
if parent is None:
return None
return parent.actionHandler.administrators
return parent.administrators
def getDirectoryAbsolutePath(self):
return self.parent.absolutePath
def getIsRemote(self):
return self.resource.isRemote
def getModificationTime(self):
return self.resource.modificationTime
def getParent(self):
resourceParent = self.resource.parent
if resourceParent is None:
def getParentUsers(self, contentName):
parent = self.parent
if parent is None:
return None
return resourceParent.dataHolder
return parent.getUsers(contentName)
def getSimpleLabel(self):
return _("Untitled Object #%s") % self.localId
def getSubPathInternUri(self, subPath):
assert not subPath or subPath[0] != "/"
uri = self.uriInternPath
if subPath is not None:
if uri[-1] == "/":
uri = "%s%s" % (uri, subPath)
def getStylesheet(self):
if self._stylesheet is None:
stylesheetLocation = self.stylesheetLocation
if stylesheetLocation is None:
return None
import dataholders
try:
stylesheetPrototype = self.walkToLocation(stylesheetLocation)
except faults.PathNotFound:
return None
import stylesheets
stylesheetInternalWay = steps.XmlStylesheetStep(self.internalWay)
uriWay = self.uriWay
if uriWay is None:
stylesheetUriWay = None
else:
uri = "%s/%s" % (uri, subPath)
return uri
stylesheetUriWay = steps.UriStep(uriWay, "stylesheet")
self._stylesheet = stylesheets.StylesheetImplementation(
stylesheetPrototype, self,
internalWay = stylesheetInternalWay, uriWay = stylesheetUriWay)
stylesheet = self._stylesheet
return stylesheet
def getSystemAbsolutePath(self):
return self.resource.systemAbsolutePath
def getUriAbsolutePath(self):
return self.resource.uriAbsolutePath
def getUriDirectoryAbsolutePath(self):
return self.uriParent.uriAbsolutePath
def getUriDirectoryInternPath(self):
return self.uriParent.uriInternPath
def getUriFirstCommonAncestor(self, uriAbsolutePath):
return self.resource.getUriFirstCommonAncestor(
uriAbsolutePath).dataHolder
def getUriInternPath(self):
return self.resource.uriInternPath
def getUriParent(self):
resourceUriParent = self.resource.uriParent
if resourceUriParent is None:
return None
return resourceUriParent.dataHolder
def getUsers(self, modeName):
def getStylesheetLocation(self):
parent = self.parent
if parent is None:
return None
return parent.actionHandler.getUsers(modeName)
parentDataHolder = parent.dataHolder
if parentDataHolder is None:
return None
return parentDataHolder.stylesheetLocation
def getUsers(self, contentName):
return self.getParentUsers(contentName)
def isContentAccessAuthorized(self, contentName):
users = self.getUsers(contentName)
if users is not None and users.containsUser():
return True
administrators = self.administrators
return administrators is not None and administrators.containsUser()
def setup(self):
"""Setup data holder.
@ -186,7 +170,11 @@ class DataHolder(actionhandlers.ActionHandlerMixin, object):
and os.path.isdir(systemAbsolutePath):
realClass = XmlHolder
if realClass is None:
if self.mimeType == "text/x-python-src":
if self.mimeType in ("image/gif", "image/jpeg", "image/png"):
realClass = ImageHolder
elif self.mimeType == "text/plain":
realClass = TextPlainHolder
elif self.mimeType == "text/x-python-src":
realClass = PythonHolder
else:
realClass = StaticDataHolder
@ -197,233 +185,188 @@ class DataHolder(actionhandlers.ActionHandlerMixin, object):
def setupDataHolder(self):
raise NotImplementedError
absolutePath = property(getAbsolutePath)
absoluteUri = property(getAbsoluteUri)
administrators = property(getAdministrators)
directoryAbsolutePath = property(getDirectoryAbsolutePath)
isRemote = property(getIsRemote)
modificationTime = property(getModificationTime)
parent = property(getParent)
simpleLabel = property(getSimpleLabel)
systemAbsolutePath = property(getSystemAbsolutePath)
uriAbsolutePath = property(getUriAbsolutePath)
uriDirectoryAbsolutePath = property(getUriDirectoryAbsolutePath)
uriDirectoryInternPath = property(getUriDirectoryInternPath)
uriInternPath = property(getUriInternPath)
uriParent = property(getUriParent)
class PythonHolder(DataHolder):
defaultFileNameExtension = ".py"
mimeType = "text/x-python-src"
def output(self):
try:
return execfile(self.absolutePath)
except IOError, error:
if error.errno != 2:
raise
return execfile(self.systemAbsolutePath)
def outputSource(self):
try:
dataFile = file(self.absolutePath, "rb")
except IOError, error:
if error.errno != 2:
raise
dataFile = file(self.systemAbsolutePath, "rb")
data = dataFile.read()
dataFile.close()
return environs.getVar("httpRequestHandler").outputData(
data, contentLocation = self.uriAbsolutePath,
mimeType = self.mimeType, modificationTime = self.modificationTime)
def setupDataHolder(self):
pass
stylesheet = property(getStylesheet)
stylesheetLocation = property(getStylesheetLocation)
class StaticDataHolder(DataHolder):
data = None
methodActionNames = DataHolder.methodActionNames.copy()
methodActionNames.update({
"styled": None, # By defaut a static object has no HTML output.
"unstyled": None, # By defaut a static object has no HTML output.
})
def output(self):
return environs.getVar("httpRequestHandler").outputData(
self.data, contentLocation = self.uriAbsolutePath,
mimeType = self.mimeType, modificationTime = self.modificationTime)
def doHttpRequest(self, station):
return self.doHttpSource(station)
def outputSource(self):
return self.output()
def setupDataHolder(self):
def loadData(self):
try:
dataFile = file(self.absolutePath, "rb")
except IOError, error:
if error.errno != 2:
raise
dataFile = file(self.systemAbsolutePath, "rb")
self.data = dataFile.read()
data = dataFile.read()
dataFile.close()
return data
def outputHttpSource(self):
environs.getVar("httpRequestHandler").outputData(
self.data, contentLocation = self.uriAbsolutePath,
mimeType = self.mimeType, modificationTime = self.modificationTime)
def setupDataHolder(self):
self.data = self.loadData()
class XmlHolder(DataHolder):
_rootElement = None
_stylesheet = None
## context = None
class ImageHolder(StaticDataHolder):
methodActionNames = StaticDataHolder.methodActionNames.copy()
methodActionNames.update({
"styled": "doHttpStyled",
"unstyled": "doHttpUnstyled",
})
def generateHtml(self, layout):
import html
layout.append(html.img(src = self.uri))
return True
class PythonHolder(StaticDataHolder):
_data = None
defaultFileNameExtension = ".py"
mimeType = "text/x-python-src"
def evaluate(self, httpNames):
if httpNames and httpNames[0] == "source":
return self, httpNames
try:
execfile(self.absolutePath)
except IOError, error:
if error.errno != 2:
raise
execfile(self.systemAbsolutePath)
result = stations.Terminus()
return result, httpNames
def getData(self):
if self._data is None:
self._data = self.loadData()
return self._data
def setupDataHolder(self):
# Don't load the data, because the evaluate method calls function
# execfile, which executes directly the file.
pass
data = property(getData)
class TextPlainHolder(StaticDataHolder):
methodActionNames = StaticDataHolder.methodActionNames.copy()
methodActionNames.update({
"styled": "doHttpStyled",
})
def doHttpRequest(self, station):
return self.doHttpStyled(station)
def generateHtml(self, layout):
import html
layout.append(html.pre(self.data))
return True
class XmlHolder(documents.DocumentMixin, DataHolder):
defaultFileNameExtension = ".xml"
doc = None
isTemporary = False
mimeType = "text/xml"
def __del__(self):
## if self.context is not None:
## xpaths.unregisterFunctions(self.context)
## self.context.xpathFreeContext()
## del self.context
if self.doc is not None:
self.doc.freeDoc()
del self.doc
def deletePublicName(self):
self.rootNode.unsetProp("publicName")
def deleteStorage(self):
try:
deleteCachedDataHolder(self.absoluteUri)
except KeyError:
pass
def destroy(self):
parent = self.parent
if parent is not None:
parent.itemDestroyed(self)
os.remove(self.absolutePath)
def evaluateXpath(self, xpath, contextNode = None):
if not xpath:
return [contextNode]
xpathContext = environs.getVar("application").xpathContext
if xpathContext.contextDoc() != self.doc:
xpathContext.setContextDoc(self.doc)
if contextNode is None:
contextNode = self.rootNode
# LibXML2 Python binding bug: contextNode() fails when the context node
# is None.
# if xpathContext.contextNode() != contextNode:
# xpathContext.setContextNode(contextNode)
xpathContext.setContextNode(contextNode)
try:
return xpathContext.xpathEval(xpath)
except libxml2.xpathError:
raise libxml2.xpathError("xmlXPathEval(%s) failed" % xpath)
def getLocalId(self):
return os.path.splitext(
self.resource.fileSystemHierarchicalStep.name)[0]
hierarchicalWay = self.hierarchicalWay
if hierarchicalWay is None:
way = self.internalWay
else:
way = self.hierarchicalWay
return way.name
def getActionHandler(self):
return self.rootElement.actionHandler
def getAdministrators(self):
return self.rootElement.getAdministrators()
def getModel(self, id):
nodes = self.evaluateXpath('//xforms:model')
if not nodes:
return None
modelNode = nodes[0]
import xforms
return xforms.Model(modelNode, self)
def getBind(self):
return None
def getChildInstanceDataXpath(self):
return ""
def getDataHolder(self):
return self
def getModelId(self):
return None
def getPublicName(self):
return self.rootNode.prop("publicName")
def getRootElement(self):
if self._rootElement is None:
self._rootElement = elements.newElement(
self.rootNode, dataHolder = self)
return self._rootElement
def getUsers(self, contentName):
return self.rootElement.getUsers(contentName)
def getRootNode(self):
return self.doc.getRootElement()
def getStylesheet(self):
if self._stylesheet is None:
stylesheetLocation = self.stylesheetLocation
if stylesheetLocation is None:
return None
import dataholders
stylesheet = walkToLocation(stylesheetLocation)
if stylesheet is None:
return None
self._stylesheet = stylesheet
return self._stylesheet
def getStylesheetLocation(self):
parent = self.parent
if parent is None:
return None
return parent.stylesheetLocation
def outputDoc(self):
if self.outputMimeType in (None, "text/html"):
## libxml2.lineNumbersDefault(1)
## libxml2.substituteEntitiesDefault(1)
stylesheet = self.stylesheet
if stylesheet is None:
return self.outputDocUnstyled()
stylesheetHolder = stylesheet.dataHolder
stylesheetStyle = libxslt.parseStylesheetDoc(stylesheetHolder.doc)
styledDoc = stylesheetStyle.applyStylesheet(self.doc, None)
data = stylesheetStyle.saveResultToString(styledDoc)
styledDoc.freeDoc()
stylesheetStyle.freeStylesheet()
return environs.getVar("httpRequestHandler").outputData(
data, contentLocation = self.uriAbsolutePath,
mimeType = "text/html")
else:
return self.outputSource()
def outputDocUnstyled(self):
data = self.doc.serialize()
return environs.getVar("httpRequestHandler").outputData(
def outputHttpSource(self):
data = self.serialize()
environs.getVar("httpRequestHandler").outputData(
data, contentLocation = self.uriAbsolutePath,
mimeType = self.mimeType)
def outputSource(self):
data = self.doc.serialize()
return environs.getVar("httpRequestHandler").outputData(
data, contentLocation = self.uriAbsolutePath,
mimeType = self.mimeType)
mimeType = self.mimeType, modificationTime = self.modificationTime)
def save(self):
libxml2.keepBlanksDefault(0)
publicName = self.publicName
if publicName and publicName != self.localId:
localId = self.localId
if publicName and publicName != localId:
isRenamed = True
oldLocalId = localId
oldAbsolutePath = self.absolutePath
try:
deleteCachedDataHolder(self.absoluteUri)
except KeyError:
isCached = False
else:
isCached = True
localId = publicName
if self.defaultFileNameExtension:
fileName = localId + self.defaultFileNameExtension
else:
fileName = localId
resource = self.resource
resource.fileSystemHierarchicalStep.name = fileName
resource.fileSystemStep.name = fileName
resource.uriStep.name = localId
#~ if self.defaultFileNameExtension:
#~ localId = publicName + self.defaultFileNameExtension
#~ else:
#~ localId = publicName
internalWay = self._internalWay
if internalWay is not None:
internalWay.name = localId
hierarchicalWay = self._hierarchicalWay
if hierarchicalWay is not None:
hierarchicalWay.name = localId
uriWay = self._uriWay
if uriWay is not None:
uriWay.name = localId
else:
isRenamed = False
del self.publicName
data = self.doc.serialize(format = 1)
data = self.node.serialize(format = 1)
self.publicName = publicName
absolutePath = self.absolutePath
if isRenamed:
os.rename(oldAbsolutePath, absolutePath)
if isCached:
dataHoldersCache = environs.getVar("dataHoldersCache")
assert self.absoluteUri not in dataHoldersCache
dataHoldersCache[self.absoluteUri] = self
dataFile = file(absolutePath, "wb")
dataFile.write(data)
dataFile.close()
if isRenamed:
parent = self.parent
if parent is not None:
parent.itemRenamed(self, oldLocalId)
def setPermanentLocalId(self):
publicName = self.publicName
@ -431,14 +374,17 @@ class XmlHolder(DataHolder):
localId = publicName
else:
localId = self.parent.actionHandler.newItemLocalId()
if self.defaultFileNameExtension:
fileName = localId + self.defaultFileNameExtension
else:
fileName = localId
resource = self.resource
resource.fileSystemHierarchicalStep.name = fileName
resource.fileSystemStep.name = fileName
resource.uriStep.name = localId
if self.defaultFileNameExtension:
localId = localId + self.defaultFileNameExtension
internalWay = self._internalWay
if internalWay is not None:
internalWay.name = localId
hierarchicalWay = self._hierarchicalWay
if hierarchicalWay is not None:
hierarchicalWay.name = localId
uriWay = self._uriWay
if uriWay is not None:
uriWay.name = localId
def setPublicName(self, publicName):
self.rootNode.setProp("publicName", publicName)
@ -451,7 +397,7 @@ class XmlHolder(DataHolder):
"""
defaultHolderClass = XmlHolder
if self.doc is None:
if self.node is None:
if self.isRemote:
raise Exception("FIXME, TODO: download data.")
else:
@ -484,7 +430,7 @@ class XmlHolder(DataHolder):
<directory
schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0"/>
xmlns="http://www.entrouvert.org/namespaces/expression/0.0"/>
"""
else:
dataFile = file(absolutePath, "rb")
@ -493,16 +439,16 @@ class XmlHolder(DataHolder):
try:
if self.mimeType == 'text/html':
# FIXME: None instead of "UTF-8" doesn't work for unicode files.
self.doc = libxml2.htmlParseDoc(data, "UTF-8")
self.node = libxml2.htmlParseDoc(data, "UTF-8")
else:
self.doc = libxml2.parseDoc(data)
self.node = libxml2.parseDoc(data)
self.publicName = self.localId
except libxml2.parserError:
logs.info(
"""Error while parsing XML file at "%s".""" % absolutePath)
raise
self.doc.xincludeProcess()
#self.context = self.doc.xpathNewContext()
self.node.xincludeProcess()
#self.context = self.node.xpathNewContext()
node = self.rootNode
if self.mimeType == 'text/html':
@ -519,47 +465,18 @@ class XmlHolder(DataHolder):
self.setupXml()
def setupXml(self):
if not self.isTemporary:
dataHoldersCache = environs.getVar(
"dataHoldersCache", default = None)
if dataHoldersCache is not None:
assert self.absoluteUri not in dataHoldersCache
dataHoldersCache[self.absoluteUri] = self
pass
## self.registerXpathNamespaces()
## xpaths.registerFunctions(self.context)
def walk(self, httpNames):
environs.push(
_level = "walk",
currentActionHandler = self)
try:
return self.rootElement.walk(httpNames)
finally:
environs.pull(_level = "walk")
def walkToItem(self, httpNames):
return self.rootElement, httpNames
actionHandler = property(getActionHandler)
administrators = property(getAdministrators)
dataHolder = property(getDataHolder)
localId = property(getLocalId)
modelId = property(getModelId)
publicName = property(getPublicName, setPublicName, deletePublicName)
rootElement = property(getRootElement)
rootNode = property(getRootNode)
stylesheet = property(getStylesheet)
stylesheetLocation = property(getStylesheetLocation)
def deleteCachedDataHolder(location):
assert location
absoluteUri = locations.getAbsoluteUri(location)
dataHoldersCache = environs.getVar("dataHoldersCache")
del dataHoldersCache[absoluteUri]
def getCachedDataHolder(location):
assert location
absoluteUri = locations.getAbsoluteUri(location)
dataHoldersCache = environs.getVar("dataHoldersCache")
if absoluteUri not in dataHoldersCache:
return None
return dataHoldersCache[absoluteUri]
def newInstance(namespaceUri, elementName, schemaLocation, descriptionLocation,
@ -570,19 +487,15 @@ def newInstance(namespaceUri, elementName, schemaLocation, descriptionLocation,
else:
itemLocalId = directory.newItemLocalId()
if fileNameExtension:
itemFileName = itemLocalId + fileNameExtension
else:
itemFileName = itemLocalId
itemLocalId = itemLocalId + fileNameExtension
directoryHolder = directory.dataHolder
itemUriStep = steps.UriStep(directoryHolder.resource.uriStep, itemLocalId)
itemFileSystemStep = steps.FileSystemStep(
directoryHolder.resource.fileSystemStep, itemFileName)
itemFileSystemHierarchicalStep = steps.FileSystemHierarchicalStep(
directoryHolder.resource.fileSystemHierarchicalStep, itemFileName)
itemResource = resources.LocalResource(
itemUriStep, itemFileSystemStep, itemFileSystemHierarchicalStep)
item = XmlHolder(itemResource)
itemInternalWay = steps.FileSystemStep(directory.internalWay, itemLocalId)
directoryUriWay = directory.uriWay
if directoryUriWay is None:
itemUriWay = None
else:
itemUriWay = steps.UriStep(directoryUriWay, itemLocalId)
itemHolder = XmlHolder(itemInternalWay, None, itemUriWay)
itemData = """\
<?xml version="1.0"?>
<%(elementName)s
@ -595,42 +508,7 @@ def newInstance(namespaceUri, elementName, schemaLocation, descriptionLocation,
"namespaceUri": namespaceUri,
"schemaLocation": schemaLocation,
}
item.doc = libxml2.parseDoc(itemData)
item.isTemporary = temporary
item.setupDataHolder()
return item
def walkToLocation(location):
if locations.isLocalUri(location):
uriInternPath = locations.getUriInternPath(location)
httpNames = []
while uriInternPath:
dataHolder = getCachedDataHolder(uriInternPath)
if dataHolder is not None:
return dataHolder.walk(httpNames)
i = uriInternPath.rfind("/")
name = uriInternPath[i + 1:]
if name:
httpNames.insert(0, name)
if i == 0:
if not name:
raise Exception(
"Root data holder %s is not cached in %s." % (
locations.getAbsoluteUri("/"),
environs.getVar("dataHoldersCache")))
uriInternPath = "/"
else:
uriInternPath = uriInternPath[:i]
else:
dataHolder = getCachedDataHolder(location)
if dataHolder is not None:
return dataHolder.actionHandler
resource = resources.RemoteResource(location)
locationCore, locationExtension = os.path.splitext(location)
mimeType = None
if locationExtension in mimeTypes:
mimeType = mimeTypes[locationExtension]
dataHolder = DataHolder(resource, mimeType = mimeType)
dataHolder.setup()
return dataHolder
itemHolder.node = libxml2.parseDoc(itemData)
itemHolder.isTemporary = temporary
itemHolder.setupDataHolder()
return itemHolder

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -37,18 +36,48 @@ import faults
import logs
import modules
import namespaces
import resources
import stations
import steps
class Directory(elements.Element):
_items = None
def getItem(self, itemLocalId):
uri = self.dataHolder.uriInternPath
if uri[-1] == "/":
itemUri = "%s%s" % (uri, itemLocalId)
else:
itemUri = "%s/%s" % (uri, itemLocalId)
return dataholders.walkToLocation(itemUri)
if self._items is None or itemLocalId not in self._items:
itemLocalIds = self.itemLocalIds
if itemLocalId not in itemLocalIds:
return None
itemLocation = self.itemLocations[itemLocalId]
itemLocationCore, itemLocationExtension = os.path.splitext(
itemLocation)
sourceMimeType = None
if itemLocationExtension in dataholders.mimeTypes:
sourceMimeType = dataholders.mimeTypes[itemLocationExtension]
elif itemLocationExtension != "":
logs.debug("""\
Unknown file name extension = "%s", length = %d, for file "%s" at "%s".\
""" % (
itemLocationExtension, len(itemLocationExtension),
itemLocation, self.absolutePath))
# FIXME TODO: Handle the case where itemLocation is a file
# path instead of a file name: Create missing file system
# hierarchical steps and directoryHolders.
assert "/" not in itemLocation
if self._items is None:
self._items = {}
itemInternalWay = steps.FileSystemStep(
self.internalWay, itemLocalId)
uriWay = self.uriWay
if uriWay is None:
itemUriWay = None
else:
itemUriWay = steps.UriStep(uriWay, itemLocalId)
item = dataholders.DataHolder(
itemInternalWay, None, itemUriWay, mimeType = sourceMimeType)
item.setup()
self._items[itemLocalId] = item
return self._items[itemLocalId]
def getItemDescriptionLocation(self):
descriptionLocationNodes = self.evaluateXpath("@itemDescription")
@ -62,6 +91,17 @@ class Directory(elements.Element):
for nameNode in self.evaluateXpath("yep:items/yep:item/@name")]
def getItemLocations(self):
dataHolder = self.dataHolder
absolutePath = dataHolder.absolutePath
if os.path.exists(absolutePath):
fileNames = os.listdir(absolutePath)
else:
fileNames = []
systemAbsolutePath = dataHolder.systemAbsolutePath
if os.path.exists(systemAbsolutePath):
for fileName in os.listdir(systemAbsolutePath):
if fileName not in fileNames:
fileNames.append(fileName)
itemLocations = {}
itemsNode = self.evaluateXpath("yep:items")[0]
for itemLocalId in self.itemLocalIds:
@ -71,34 +111,30 @@ class Directory(elements.Element):
itemLocation = itemLocationNodes[0].content
else:
itemLocation = itemLocalId
dataHolder = self.dataHolder
absolutePath = dataHolder.absolutePath
if os.path.exists(absolutePath):
fileNames = os.listdir(absolutePath)
else:
fileNames = []
systemAbsolutePath = dataHolder.systemAbsolutePath
if os.path.exists(systemAbsolutePath):
for fileName in os.listdir(systemAbsolutePath):
if fileName not in fileNames:
fileNames.append(fileName)
for fileName in fileNames:
if fileName[-1] == "~":
continue
fileNameCore, fileNameExtension = os.path.splitext(
fileName)
if fileNameCore != itemLocation:
continue
if fileNameExtension in (".pyc", ".pyo"):
continue
itemLocation = fileName
break
else:
# FIXME?
itemLocation = itemLocalId
itemLocations[itemLocalId] = itemLocation
if itemLocation in fileNames:
itemLocations[itemLocalId] = itemLocation
return itemLocations
def itemDestroyed(self, item):
"""Called before an item (hierarchical) is destroyed"""
if self._items is None:
return
itemLocalId = item.localId
if itemLocalId not in self._items:
return
del self._items[itemLocalId]
if not self._items:
del self._items
def itemRenamed(self, item, itemOldLocalId):
"""Called after an item (hierarchical) is renamed"""
if self._items is None or itemOldLocalId not in self._items:
return
del self._items[itemOldLocalId]
self._items[item.localId] = item
def newItemLocalId(self):
# FIXME: Compute a real localId.
import whrandom
@ -117,79 +153,96 @@ class Directory(elements.Element):
path = "%s/doHttpRequest" % path
else:
path = "doHttpRequest"
return dataholders.walkToLocation(path)
return self.walkToLocation(path)
return elements.Element.output(self)
def walk1(self, httpNames):
if httpNames:
dataHolder = self.dataHolder
httpName = httpNames[0]
itemLocalId, fileNameExtension = os.path.splitext(httpName)
itemLocalIds = self.itemLocalIds
if itemLocalId in itemLocalIds:
itemLocation = self.itemLocations[itemLocalId]
itemLocationCore, itemLocationExtension = os.path.splitext(
itemLocation)
outputMimeType = None
if fileNameExtension in dataholders.mimeTypes:
outputMimeType = dataholders.mimeTypes[fileNameExtension]
else:
outputMimeType = "text/html"
sourceMimeType = None
if itemLocationExtension in dataholders.mimeTypes:
sourceMimeType = dataholders.mimeTypes[
itemLocationExtension]
elif itemLocationExtension != "":
logs.debug("""\
Unknown file name extension = "%s", length = %d, for file "%s" at "%s"\
""" % (
itemLocationExtension, len(itemLocationExtension),
itemLocation, dataHolder.absolutePath))
itemUriStep = steps.UriStep(
dataHolder.resource.uriStep, httpName)
itemDataHolder = dataholders.getCachedDataHolder(
itemUriStep.absoluteUri)
if itemDataHolder is None:
itemFileSystemStep = steps.FileSystemStep(
dataHolder.resource.fileSystemStep, itemLocation)
# FIXME TODO: Handle the case where itemLocation is a file
# path instead of a file name: Create missing file system
# hierachical steps, resources and directoryHolders.
assert "/" not in itemLocation
itemFileSystemHierarchicalStep \
= steps.FileSystemHierarchicalStep(
dataHolder.resource.fileSystemHierarchicalStep,
itemLocation)
itemResource = resources.LocalResource(
itemUriStep, itemFileSystemStep,
itemFileSystemHierarchicalStep)
itemDataHolder = dataholders.DataHolder(
itemResource, mimeType = sourceMimeType,
outputMimeType = outputMimeType)
itemDataHolder.setup()
return itemDataHolder.walk(httpNames[1:])
return elements.Element.walk1(self, httpNames)
#~ def walk1(self, httpNames):
#~ if httpNames:
#~ dataHolder = self.dataHolder
#~ httpName = httpNames[0]
#~ itemLocalId, fileNameExtension = os.path.splitext(httpName)
#~ itemLocalIds = self.itemLocalIds
#~ if itemLocalId in itemLocalIds:
#~ itemLocation = self.itemLocations[itemLocalId]
#~ itemLocationCore, itemLocationExtension = os.path.splitext(
#~ itemLocation)
#~ outputMimeType = None
#~ if fileNameExtension in dataholders.mimeTypes:
#~ outputMimeType = dataholders.mimeTypes[fileNameExtension]
#~ else:
#~ outputMimeType = "text/html"
#~ sourceMimeType = None
#~ if itemLocationExtension in dataholders.mimeTypes:
#~ sourceMimeType = dataholders.mimeTypes[
#~ itemLocationExtension]
#~ elif itemLocationExtension != "":
#~ logs.debug("""\
#~ Unknown file name extension = "%s", length = %d, for file "%s" at "%s"\
#~ """ % (
#~ itemLocationExtension, len(itemLocationExtension),
#~ itemLocation, dataHolder.absolutePath))
#~ itemUriStep = steps.UriStep(
#~ dataHolder.resource.uriStep, httpName)
#~ itemFileSystemStep = steps.FileSystemStep(
#~ dataHolder.resource.fileSystemStep, itemLocation)
#~ # FIXME TODO: Handle the case where itemLocation is a file
#~ # path instead of a file name: Create missing file system
#~ # hierachical steps, resources and directoryHolders.
#~ assert "/" not in itemLocation
#~ itemFileSystemHierarchicalStep \
#~ = steps.FileSystemHierarchicalStep(
#~ dataHolder.resource.fileSystemHierarchicalStep,
#~ itemLocation)
#~ itemResource = resources.LocalResource(
#~ itemUriStep, itemFileSystemStep,
#~ itemFileSystemHierarchicalStep)
#~ itemDataHolder = dataholders.DataHolder(
#~ itemResource, mimeType = sourceMimeType,
#~ outputMimeType = outputMimeType)
#~ itemDataHolder.setup()
#~ return itemDataHolder.walk(httpNames[1:])
#~ return elements.Element.walk1(self, httpNames)
def walkActions1(self, httpNames):
name = httpNames[0]
if name.startswith("new-"):
try:
namespaceName, elementName = name[len("new-"):].split("-", 1)
constructor = modules.getHolderConstructor(
namespaces.getUri(namespaceName), elementName)
except (KeyError, ValueError):
if httpNames[-1] == "exists":
return False
raise faults.PathNotFound("/".join(httpNames))
if not self.modeAccessIsAuthorized(name):
if httpNames[-1] == "exists" and len(httpNames) == 2:
return True
if httpNames[-1] == "isAuthorized":
return False
raise faults.PathUnauthorized("/".join(httpNames))
newItemHolder = constructor(self, temporary = True)
return newItemHolder.walk(["new"] + httpNames[1:])
return elements.Element.walkActions1(self, httpNames)
#~ def walkActions1(self, httpNames):
#~ name = httpNames[0]
#~ if name.startswith("new-"):
#~ try:
#~ namespaceName, elementName = name[len("new-"):].split("-", 1)
#~ constructor = modules.getHolderConstructor(
#~ namespaces.getUri(namespaceName), elementName)
#~ except (KeyError, ValueError):
#~ if httpNames[-1] == "exists":
#~ return False
#~ raise faults.PathNotFound("/".join(httpNames))
#~ if not self.modeAccessIsAuthorized(name):
#~ if httpNames[-1] == "exists" and len(httpNames) == 2:
#~ return True
#~ if httpNames[-1] == "isAuthorized":
#~ return False
#~ raise faults.PathUnauthorized("/".join(httpNames))
#~ newItemHolder = constructor(self, temporary = True)
#~ return newItemHolder.walk(["new"] + httpNames[1:])
#~ return elements.Element.walkActions1(self, httpNames)
def walkToItem(self, httpNames):
if not httpNames:
return elements.Element.walkToItem(self, httpNames)
itemName = httpNames[0]
itemLocalIds = self.itemLocalIds
if itemName in itemLocalIds:
itemLocalId = itemName
else:
for fileName in itemLocalIds:
fileNameCore, fileNameExtension = os.path.splitext(fileName)
if itemName == fileNameCore:
itemLocalId = fileName
break
else:
return elements.Element.walkToItem(self, httpNames)
item = self.getItem(itemLocalId)
if item is None:
return elements.Element.walkToItem(self, httpNames)
return item, httpNames[1:]
itemLocalIds = property(getItemLocalIds)
itemLocations = property(getItemLocations)
@ -198,6 +251,16 @@ Unknown file name extension = "%s", length = %d, for file "%s" at "%s"\
class DirectoryHolder(dataholders.XmlHolder):
defaultFileNameExtension = None
def destroy(self):
parent = self.parent
if parent is not None:
parent.itemDestroyed(self)
absolutePath = self.absolutePath
indexAbsolutePath = os.path.join(absolutePath, "index.xml")
os.remove(indexAbsolutePath)
# FIXME: Handle non empty directories.
os.rmdir(absolutePath)
def getDirectoryAbsolutePath(self):
return self.absolutePath
@ -213,17 +276,6 @@ class DirectoryHolder(dataholders.XmlHolder):
def getUriDirectoryInternPath(self):
return self.uriInternPath
def deleteStorage(self):
absolutePath = self.absolutePath
try:
deleteCachedDataHolder(self.absoluteUri)
except KeyError:
pass
indexAbsolutePath = os.path.join(absolutePath, "index.xml")
os.remove(indexAbsolutePath)
# FIXME: Handle non empty directories.
os.rmdir(absolutePath)
def save(self):
absolutePath = self.absolutePath
if not os.path.exists(absolutePath):
@ -231,24 +283,23 @@ class DirectoryHolder(dataholders.XmlHolder):
indexAbsolutePath = os.path.join(absolutePath, "index.xml")
libxml2.keepBlanksDefault(0)
publicName = self.publicName
if publicName and publicName != self.localId:
localId = self.localId
if publicName and publicName != localId:
isRenamed = True
oldLocalId = localId
oldAbsolutePath = absolutePath
try:
deleteCachedDataHolder(self.absoluteUri)
except KeyError:
isCached = False
else:
isCached = True
localId = publicName
if self.defaultFileNameExtension:
fileName = localId + self.defaultFileNameExtension
else:
fileName = localId
resource = self.resource
resource.fileSystemHierarchicalStep.name = fileName
resource.fileSystemStep.name = fileName
resource.uriStep.name = localId
#~ if self.defaultFileNameExtension:
#~ localId = publicName + self.defaultFileNameExtension
#~ else:
#~ localId = publicName
self._internalWay.name = localId
hierarchicalWay = self._hierarchicalWay
if hierarchicalWay is not None:
hierarchicalWay.name = localId
uriWay = self._uriWay
if uriWay is not None:
uriWay.name = localId
else:
isRenamed = False
del self.publicName
@ -257,22 +308,22 @@ class DirectoryHolder(dataholders.XmlHolder):
# Don't serialize items if they were generated automaticaly.
itemsNode = itemsNodes[0]
itemsNode.unlinkNode()
data = self.doc.serialize(format = 1)
data = self.node.serialize(format = 1)
self.rootNode.addChild(itemsNode)
else:
data = self.doc.serialize(format = 1)
data = self.node.serialize(format = 1)
self.publicName = publicName
if isRenamed:
absolutePath = self.absolutePath
indexAbsolutePath = os.path.join(absolutePath, "index.xml")
os.rename(oldAbsolutePath, absolutePath)
if isCached:
dataHoldersCache = environs.getVar("dataHoldersCache")
assert self.absoluteUri not in dataHoldersCache
dataHoldersCache[self.absoluteUri] = self
dataFile = file(indexAbsolutePath, "wb")
dataFile.write(data)
dataFile.close()
if isRenamed:
parent = self.parent
if parent is not None:
parent.itemRenamed(self, oldLocalId)
def setupXml(self):
dataholders.XmlHolder.setupXml(self)
@ -291,13 +342,14 @@ class DirectoryHolder(dataholders.XmlHolder):
for fileName in fileNames:
if fileName[-1] == "~":
continue
itemLocalId, fileNameExtension = os.path.splitext(fileName)
if itemLocalId in ("CVS", "index"):
if fileName in ("CVS", "index.xml"):
continue
fileNameCore, fileNameExtension = os.path.splitext(fileName)
if fileNameExtension in (".pyc", ".pyo"):
continue
if itemLocalId not in itemLocalIds:
itemLocalIds.append(itemLocalId)
if fileName not in itemLocalIds:
itemLocalIds.append(fileName)
itemLocalIds.sort()
itemsNode = self.rootNode.newChild(None, "items", None)
itemsNode.newProp("generation", "automatic")
for itemLocalId in itemLocalIds:
@ -313,8 +365,8 @@ class DirectoryHolder(dataholders.XmlHolder):
def newDirectoryHolder(directory, temporary = False):
return dataholders.newInstance(
namespaces.yep.uri, "directory", "/schemas/Directory.xsd",
"/descriptions/Directory.xml", directory, fileNameExtension = None,
temporary = temporary)
"/descriptions/Directory.xml", directory,
fileNameExtension = None, temporary = temporary)
modules.registerElementClass(namespaces.yep.uri, "directory", Directory)

97
src/core/documents.py Normal file
View File

@ -0,0 +1,97 @@
# -*- coding: UTF-8 -*-
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""XML Documents Module"""
import libxml2
import elements
import environs
import logs
import namespaces
import nodes
import stations
import steps
class DocumentMixin(nodes.NodeWrapper):
_rootElement = None
def __del__(self):
if self.node is not None:
self.node.freeDoc()
del self.node
def evaluateXpath(self, xpath, contextNode = None):
if not xpath:
return [contextNode]
xpathContext = environs.getVar("application").xpathContext
if xpathContext.contextDoc() != self.node:
xpathContext.setContextDoc(self.node)
if contextNode is None:
contextNode = self.rootNode
if contextNode is None:
return []
# LibXML2 Python binding bug: contextNode() fails when the context node
# is None.
# if xpathContext.contextNode() != contextNode:
# xpathContext.setContextNode(contextNode)
xpathContext.setContextNode(contextNode)
try:
return xpathContext.xpathEval(xpath)
except libxml2.xpathError:
raise libxml2.xpathError("xmlXPathEval(%s) failed" % xpath)
def getRootElement(self):
if self._rootElement is None:
rootNode = self.rootNode
if rootNode is None:
return None
rootElementInternalWay = steps.XmlRootElementStep(self.internalWay)
# There doesn't exist any URI path to access a rootElement
# => no uriWay.
self._rootElement = elements.newElement(
rootNode, rootElementInternalWay)
rootElement = self._rootElement
return rootElement
def getRootNode(self):
try:
return self.node.getRootElement()
except libxml2.treeError:
return None
rootElement = property(getRootElement)
rootNode = property(getRootNode)
class TemporaryDocument(DocumentMixin, stations.AbstractStation):
def __init__(self, node):
DocumentMixin.__init__(self, node)
stations.AbstractStation.__init__(self)
def newTemporaryDocument():
return TemporaryDocument(libxml2.newDoc("1.0"))

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -31,39 +30,34 @@ Every elements belongs to a XML holder (which is a wrapper around libxml2 docs).
import libxml2
import libxslt
import actionhandlers
import environs
import faults
import locations
import logs
import modules
import namespaces
import nodes
import stations
import steps
class Element(actionhandlers.ActionHandlerMixin, object):
_dataHolder = None
class Element(stations.AbstractStation, nodes.NodeWrapper):
_description = None
_schema = None # XML Schema.
inForm = False
node = None
parent = None
relevant = True
submitActionNames = actionhandlers.ActionHandlerMixin.submitActionNames + (
"submit",)
_schema = None # Cache for XML schema
def __init__(self, node = None, dataHolder = None, parent = None):
def __init__(self, node = None, internalWay = None, hierarchicalWay = None,
uriWay = None):
"""Do not override this method, it won't work. Override method
setupDataHolder instead.
"""
stations.AbstractStation.__init__(
self, internalWay = internalWay, hierarchicalWay = hierarchicalWay,
uriWay = uriWay)
if node is None:
node = libxml2.newNode(self.name)
self.node = node
if dataHolder is not None:
self.dataHolder = dataHolder
if parent is not None:
self.parent = parent
def deleteDataHolder(self):
del self._dataHolder
nodes.NodeWrapper.__init__(self, node)
def evaluateXpath(self, xpath, contextNode = None):
if contextNode is None:
@ -71,48 +65,59 @@ class Element(actionhandlers.ActionHandlerMixin, object):
return self.dataHolder.evaluateXpath(xpath, contextNode)
def fillPageBodyLayout(self, layout, inForm = False):
# FIXME: Obsolete method
description = self.description
if description is None:
return False
return description.fillInstancePageBodyLayout(layout, inForm = inForm)
return description.fillContextPageBodyLayout(layout, inForm = inForm)
def fillPageLayout(self, layout):
# FIXME: Obsolete method
description = self.description
if description is None:
return False
return description.fillInstancePageLayout(layout)
def generateHtml(self, layout):
import html
layout.append(html.pre(self.serialize()))
return True
def getActionHandler(self):
# FIXME: Remove this old method.
return self
def getAdministrators(self):
nodes = self.evaluateXpath("yep:administrators")
if nodes:
return UsersSet(nodes[0], parent = self)
return self.newElement(nodes[0])
dataHolder = self.dataHolder
if dataHolder is None:
return None
return dataHolder.getAdministrators()
def getDataHolder(self):
dataHolder = self._dataHolder
if dataHolder is None:
parent = self.parent
if parent is None:
return None
else:
return parent.dataHolder
else:
return dataHolder
return dataHolder.getParentAdministrators()
def getDescription(self):
if self._description is None:
descriptionLocation = self.descriptionLocation
if descriptionLocation is None:
return None
import dataholders
description = dataholders.walkToLocation(descriptionLocation)
if description is None:
try:
descriptionPrototype = self.walkToLocation(descriptionLocation)
except faults.PathNotFound:
return None
self._description = description
return self._description
import descriptions
descriptionInternalWay = steps.XmlDescriptionStep(self.internalWay)
uriWay = self.uriWay
if uriWay is None:
descriptionUriWay = None
else:
descriptionUriWay = steps.UriStep(uriWay, "description")
self._description = descriptions.DescriptionImplementation(
descriptionPrototype, self,
internalWay = descriptionInternalWay,
uriWay = descriptionUriWay)
description = self._description
return description
def getDescriptionLocation(self):
descriptionLocationNodes = self.evaluateXpath("@description")
@ -120,6 +125,13 @@ class Element(actionhandlers.ActionHandlerMixin, object):
return None
return descriptionLocationNodes[0].content
def getId(self):
sourceNodes = self.evaluateXpath("@id")
if sourceNodes:
return sourceNodes[0].content
else:
return None
def getName(self):
return self.namespaceUriAndName[1]
@ -134,12 +146,22 @@ class Element(actionhandlers.ActionHandlerMixin, object):
schemaLocation = self.schemaLocation
if schemaLocation is None:
return None
import dataholders
schema = dataholders.walkToLocation(schemaLocation)
if schema is None:
try:
schemaPrototype = self.walkToLocation(schemaLocation)
except faults.PathNotFound:
return None
self._schema = schema
return self._schema
import xmlschemas
schemaInternalWay = steps.XmlSchemaStep(self.internalWay)
uriWay = self.uriWay
if uriWay is None:
schemaUriWay = None
else:
schemaUriWay = steps.UriStep(uriWay, "schema")
self._schema = xmlschemas.SchemaImplementation(
schemaPrototype, self, internalWay = schemaInternalWay,
uriWay = schemaUriWay)
schema = self._schema
return schema
def getSchemaLocation(self):
schemaLocationNodes = self.evaluateXpath("@schema")
@ -155,58 +177,46 @@ class Element(actionhandlers.ActionHandlerMixin, object):
return None
def getType(self):
name = self.node.name
if not self.schema:
schema = self.schema
if schema is None:
return None
return self.schema.getGlobalElementType(name)
def getTypeAtXpath(self, xpath):
"""Xpath must be a simple xpath expression."""
type = self.type
if type is None:
logs.info(
"""Schema "%s" contains no type for element "%s".""" % (
self.schemaLocation, self.node.name))
while xpath:
splitedXpath = xpath.split("/", 1)
name = splitedXpath[0]
assert name
if "[" in name:
name = name[:name.index("[")]
if name[0] == "@":
# Attribute
subType = type.getAttributeType(name[1:])
else:
# Child
subType = type.getChildType(name)
if subType is None:
raise Exception("""Unknown type for %s in "%s".""" % (
name, type.name))
type = subType
if len(splitedXpath) > 1:
xpath = splitedXpath[1]
else:
xpath = None
return type
return schema.getGlobalElementType(self.node.name)
def getUsers(self, modeName):
nodes = self.evaluateXpath("""yep:users[@mode = "%s"]""" % modeName)
if nodes:
return UsersSet(nodes[0], parent = self)
return self.newElement(nodes[0])
dataHolder = self.dataHolder
if dataHolder is None:
return None
return dataHolder.getUsers(modeName)
return dataHolder.getParentUsers(modeName)
def isContentAccessAuthorized(self, contentName):
return self.dataHolder.isContentAccessAuthorized(contentName)
def layoutRequiresForm(self):
description = self.description
if description is not None:
return description.instanceLayoutRequiresForm()
return actionhandlers.ActionHandlerMixin.layoutRequiresForm(self)
return False
def output(self):
return self.dataHolder.outputDoc()
def newElement(self, elementNode):
elementInternalWay = steps.XmlElementStep(self.internalWay)
# There doesn't exist any URI path to access an element=> no uriWay.
# uriWay = self.uriWay
# if uriWay is None:
# elementUriWay = None
# else:
# elementUriWay = steps.XmlElementStep(uriWay)
return newElement(elementNode, elementInternalWay)
def outputHttpSource(self):
data = self.serialize()
dataHolder = self.dataHolder
environs.getVar("httpRequestHandler").outputData(
data, contentLocation = self.uriAbsolutePath,
mimeType = dataHolder.mimeType,
modificationTime = dataHolder.modificationTime)
def setContentAtXpath(self, xpath, content):
"""Xpath must be a simple xpath expression."""
@ -249,9 +259,6 @@ class Element(actionhandlers.ActionHandlerMixin, object):
else:
node.setContent(content)
def setDataHolder(self, dataHolder):
self._dataHolder = dataHolder
def setElementAttribute(self, prefixedName, attributeName, attributeValue):
# FIXME: Handle default namespace better.
nodes = self.evaluateXpath(prefixedName)
@ -297,10 +304,6 @@ class Element(actionhandlers.ActionHandlerMixin, object):
node.setContent(content)
def submit(self, *arguments):
fieldStorage = environs.getVar("fieldStorage")
if fieldStorage.has_key("pageName"):
pageName = fieldStorage.getvalue("pageName")
environs.setVar("pageName", pageName)
self.submitToUrl()
def submitToUrl(self, nextUrl = None):
@ -310,68 +313,74 @@ class Element(actionhandlers.ActionHandlerMixin, object):
if environs.getVar("debug"):
raise Exception(
"""Description "%s" missing""" % self.descriptionLocation)
raise faults.PathNotFound(dataHolder.uriInternPath)
raise faults.PathNotFound(self.uriInternPath)
description.submit()
if dataHolder.localId.startswith("new-"):
dataHolder.setPermanentLocalId()
dataHolder.save()
if nextUrl is None:
nextUrl = locations.getUri(dataHolder.uriInternPath)
nextUrl = self.constructUri(self.uriInternPath)
return environs.getVar("httpRequestHandler").outputRedirect(nextUrl)
def walk1(self, httpNames):
#~ def walk1(self, httpNames):
#~ description = self.description
#~ if description is not None:
#~ name = httpNames[0]
#~ if name in description.getEmailMessageNames():
#~ emailMessage = description.getInstanceEmailMessage(self, name)
#~ return emailMessage.walk(httpNames[1:])
#~ return actionhandlers.ActionHandlerMixin.walk1(self, httpNames)
#~ def walkActions1(self, httpNames):
#~ if environs.getVar("pageName") is None:
#~ description = self.description
#~ if description is not None:
#~ name = httpNames[0]
#~ if name in description.getPageNames():
#~ environs.setVar("pageName", name)
#~ return self.walkActions(httpNames[1:])
#~ modeName = httpNames[0]
#~ if modeName == "description":
#~ description = self.description
#~ if description is None:
#~ if httpNames[-1] == "exists":
#~ return False
#~ raise faults.PathNotFound("/".join(httpNames))
#~ if not self.modeAccessIsAuthorized(modeName):
#~ if httpNames[-1] == 'exists' and len(httpNames) == 2:
#~ return True
#~ if httpNames[-1] == 'isAuthorized':
#~ return False
#~ raise faults.PathUnauthorized('/'.join(httpNames))
#~ return description.walk(httpNames[1:])
#~ elif modeName == "schema":
#~ schema = self.schema
#~ if schema is None:
#~ if httpNames[-1] == "exists":
#~ return False
#~ raise faults.PathNotFound("/".join(httpNames))
#~ if not self.modeAccessIsAuthorized(modeName):
#~ if httpNames[-1] == 'exists' and len(httpNames) == 2:
#~ return True
#~ if httpNames[-1] == 'isAuthorized':
#~ return False
#~ raise faults.PathUnauthorized('/'.join(httpNames))
#~ return schema.walk(httpNames[1:])
#~ return actionhandlers.ActionHandlerMixin.walkActions1(self, httpNames)
def walkToItem(self, httpNames):
description = self.description
if description is not None:
name = httpNames[0]
if name in description.getEmailMessageNames():
emailMessage = description.getInstanceEmailMessage(self, name)
return emailMessage.walk(httpNames[1:])
return actionhandlers.ActionHandlerMixin.walk1(self, httpNames)
def walkActions1(self, httpNames):
if environs.getVar("pageName") is None:
description = self.description
if description is not None:
name = httpNames[0]
if name in description.getPageNames():
environs.setVar("pageName", name)
return self.walkActions(httpNames[1:])
modeName = httpNames[0]
if modeName == "description":
description = self.description
if description is None:
if httpNames[-1] == "exists":
return False
raise faults.PathNotFound("/".join(httpNames))
if not self.modeAccessIsAuthorized(modeName):
if httpNames[-1] == 'exists' and len(httpNames) == 2:
return True
if httpNames[-1] == 'isAuthorized':
return False
raise faults.PathUnauthorized('/'.join(httpNames))
return description.walk(httpNames[1:])
elif modeName == "schema":
schema = self.schema
if schema is None:
if httpNames[-1] == "exists":
return False
raise faults.PathNotFound("/".join(httpNames))
if not self.modeAccessIsAuthorized(modeName):
if httpNames[-1] == 'exists' and len(httpNames) == 2:
return True
if httpNames[-1] == 'isAuthorized':
return False
raise faults.PathUnauthorized('/'.join(httpNames))
return schema.walk(httpNames[1:])
elif modeName == "unstyled":
return self.do(
modeName, httpNames[1:], self.dataHolder.outputDocUnstyled)
return actionhandlers.ActionHandlerMixin.walkActions1(self, httpNames)
item, remainingHttpNames = description.walkToItem(httpNames)
if item is not None:
return item, remainingHttpNames
return stations.AbstractStation.walkToItem(self, httpNames)
actionHandler = property(getActionHandler)
administrators = property(getAdministrators)
dataHolder = property(getDataHolder, setDataHolder, deleteDataHolder)
description = property(getDescription)
descriptionLocation = property(getDescriptionLocation)
id = property(getId)
name = property(getName)
namespaceUri = property(getNamespaceUri)
namespaceUriAndName = property(getNamespaceUriAndName)
@ -387,11 +396,7 @@ class List(Element):
def __iter__(self):
nodes = self.evaluateXpath(self.itemsXpath)
for node in nodes:
yield newElement(node, parent = self)
def append(self, item):
self.node.addChild(item.node)
item.parent = self
yield self.newElement(node)
class SimpleList(Element):
@ -425,7 +430,7 @@ class UsersSet(List):
if user is None:
userAbsoluteUri = None
else:
userAbsoluteUri = user.dataHolder.absoluteUri
userAbsoluteUri = user.absoluteUri
groupAbsoluteUris = []
for item in self:
itemNode = item.node
@ -434,24 +439,24 @@ class UsersSet(List):
itemSource = item.source
if itemSource is None:
continue
itemAbsoluteUri = locations.getAbsoluteUri(itemSource)
itemAbsoluteUri = self.constructAbsoluteUri(itemSource)
if itemAbsoluteUri == userAbsoluteUri:
return True
elif itemNode.name == "group":
groupAbsoluteUris.append(itemAbsoluteUri)
if groupAbsoluteUris:
import dataholders
groupsHolder = dataholders.walkToLocation("/groups")
groups = self.walkToLocation("/groups")
groupsHolder = groups.dataHolder
for groupAbsoluteUri in groupAbsoluteUris:
group = groupsHolder.getItem(
locations.extractUriLocalId(groupAbsoluteUri))
if group is not None and group.contains(
userAbsoluteUri, authenticationMethod):
return True
if group is not None:
if group.contains(userAbsoluteUri, authenticationMethod):
return True
return False
def newElement(node, dataHolder = None, parent = None):
def newElement(node, internalWay = None, hierarchicalWay = None, uriWay = None):
namespaceUri = None
elementName = None
while True:
@ -463,16 +468,22 @@ def newElement(node, dataHolder = None, parent = None):
elementName = node.name
if namespaceUri != namespaces.yep.uri or elementName != "copy":
break
if dataHolder is None:
realDataHolder = parent.dataHolder
if hierarchicalWay is not None:
parent = internalWay.station
else:
realDataHolder = dataHolder
originalIdNodes = realDataHolder.evaluateXpath("@original", node)
parent = hierarchicalWay.station
dataHolder = parent.dataHolder
originalIdNodes = dataHolder.evaluateXpath("@original", node)
originalId = originalIdNodes[0].content
originalNodes = realDataHolder.evaluateXpath(
originalNodes = dataHolder.evaluateXpath(
"//*[@yep:id = '%s']" % originalId)
node = originalNodes[0]
elementClass = modules.getElementClass(namespaceUri, elementName)
return elementClass(node = node, dataHolder = dataHolder, parent = parent)
return elementClass(node = node, internalWay = internalWay,
hierarchicalWay = hierarchicalWay, uriWay = uriWay)
modules.registerElementClass(namespaces.yep.uri, "administrators", UsersSet)
modules.registerElementClass(namespaces.yep.uri, "users", UsersSet)
modules.setDefaultElementClass(Element)

View File

@ -82,7 +82,7 @@ class _Environ:
def clear():
"""Empty environ stack."""
threading.currentThread()._glasnostEnviron = None
threading.currentThread()._expressionEnviron = None
def delVar(name):
@ -105,7 +105,7 @@ def get(**signatureVariables):
"""
thread = threading.currentThread()
environ = thread._glasnostEnviron
environ = thread._expressionEnviron
if not signatureVariables:
return environ
while environ is not None:
@ -141,23 +141,23 @@ def initFromOther(otherEnviron, **environVariables):
environ = _Environ(environVariables)
environ.next = otherEnviron
threading.currentThread()._glasnostEnviron = environ
threading.currentThread()._expressionEnviron = environ
def initThread(thread):
"""Initialise a new thread environ."""
environ = _Environ({})
environ.next = threading.currentThread()._glasnostEnviron
thread._glasnostEnviron = environ
environ.next = threading.currentThread()._expressionEnviron
thread._expressionEnviron = environ
def isClear():
"""Test if the environ stack is empty."""
thread = threading.currentThread()
return hasattr(thread, "_glasnostEnviron") \
and thread._glasnostEnviron is None
return hasattr(thread, "_expressionEnviron") \
and thread._expressionEnviron is None
def pull(**signatureVariables):
@ -169,14 +169,14 @@ def pull(**signatureVariables):
"""
thread = threading.currentThread()
environ = thread._glasnostEnviron
environ = thread._expressionEnviron
while environ is not None:
variables = environ.variables
for name, value in signatureVariables.items():
if not variables.has_key(name) or variables[name] != value:
break
else:
thread._glasnostEnviron = environ.next
thread._expressionEnviron = environ.next
return
environ = environ.next
raise Exception("Unable to find signature in environ.")
@ -187,15 +187,15 @@ def push(**environVariables):
thread = threading.currentThread()
environ = _Environ(environVariables)
environ.next = thread._glasnostEnviron
thread._glasnostEnviron = environ
environ.next = thread._expressionEnviron
thread._expressionEnviron = environ
return environ
def set(environ):
"""Set the current environ."""
threading.currentThread()._glasnostEnviron = environ
threading.currentThread()._expressionEnviron = environ
def setVar(name, value):

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -32,20 +31,26 @@ import types
import libxml2
import dataholders
import documents
import elements
import locations
import logs
import modules
import namespaces
import stations
import steps
import widgets
class Element(elements.Element):
def __init__(self, *items, **attributes):
node = attributes.pop("node", None)
dataHolder = attributes.pop("dataHolder", None)
parent = attributes.pop("parent", None)
internalWay = attributes.pop("internalWay", None)
hierarchicalWay = attributes.pop("hierarchicalWay", None)
uriWay = attributes.pop("uriWay", None)
elements.Element.__init__(
self, node, dataHolder = dataHolder, parent = parent)
self, node, internalWay = internalWay,
hierarchicalWay = hierarchicalWay, uriWay = uriWay)
for key, value in attributes.items():
if key[-1] == "_":
key = key[:-1]
@ -53,45 +58,12 @@ class Element(elements.Element):
for item in items:
self.append(item)
def append(self, item):
assert type(item) not in (types.ListType, types.TupleType), \
"Wrong item = %s (of type %s)" % (str(item), str(type(item)))
if item is None:
return
if isinstance(item, elements.Element):
itemNode = item.node
self.node.addChild(itemNode)
dataHolder = self.dataHolder
if dataHolder is None:
if item.namespaceUri == self.namespaceUri:
itemNode.setNs(None)
else:
raise "FIXME: To do: set itemNode namespace"
else:
namespace = self.node.searchNsByHref(
dataHolder.doc, item.namespaceUri)
if namespace is None:
raise "FIXME: To do: set itemNode namespace"
else:
itemNode.setNs(namespace)
elif isinstance(item, libxml2.xmlCore):
self.node.addChild(item)
elif isinstance(item, unicode):
self.node.addContent(item.encode("UTF-8"))
else:
self.node.addContent(item)
def getAttribute(self, name):
if self.node.hasProp(name):
return self.node.prop(name)
else:
return None
def fillPageBodyLayout(self, layout, inForm = False):
return self.fillPageLayout(layout)
def fillPageLayout(self, layout):
self.dataHolder.convertInternUris()
dataHolder = self.dataHolder
dataHolder.convertInternUris()
# FIXME: When the document is parsed by htmlParseDoc, there is no
# namespace.
#nodes = self.evaluateXpath("html:body/*")
@ -106,6 +78,15 @@ class Element(elements.Element):
layout.append(node)
return True
def generateHtml(self, layout):
return self.generateHtmlImplementation(self, layout)
def getAttribute(self, name):
if self.node.hasProp(name):
return self.node.prop(name)
else:
return None
def serialize(self):
return self.node.serialize()
@ -114,7 +95,7 @@ class Element(elements.Element):
class WidgetElement(widgets.WidgetMixin, Element):
def generateHtml(self, layout):
def generateHtmlImplementation(self, implementation, layout):
node = self.node
newNode = libxml2.newNode(node.name)
attribute = node.properties
@ -132,8 +113,8 @@ class WidgetElement(widgets.WidgetMixin, Element):
newWidget.append(childNode.content)
childNode = childNode.next
continue
element = elements.newElement(childNode, parent = self)
element.generateHtml(newWidget)
element = self.newElement(childNode)
element.generateHtmlImplementation(implementation, newWidget)
childNode = childNode.next
return True
@ -163,11 +144,22 @@ class HtmlHolder(dataholders.XmlHolder):
uri = linkNode.content
if not uri:
continue
linkNode.setContent(locations.getUri(uri))
linkNode.setContent(self.constructUri(uri))
def outputDocUnstyled(self):
self.convertInternUris()
return dataholders.XmlHolder.outputDocUnstyled(self)
class HtmlImplementationMixin(object):
formCreationNeeded = None # 3 states: True, False & None (= don't know)
inForm = False
xformsDefaultModel = None
xformsModelsById = None
def generateHtmlPage(self, layout):
return self.prototype.generateHtmlImplementation(self, layout)
class HtmlImplementation(HtmlImplementationMixin,
stations.AbstractImplementation):
pass
class a(InlineLevelElement):
@ -348,11 +340,15 @@ class html(WidgetElement):
newWidget.append(childNode.content)
childNode = childNode.next
continue
element = elements.newElement(childNode, parent = self)
element.generateHtml(newWidget)
element = self.newElement(childNode)
# FIXME: Define implementation
element.generateHtmlImplementation(implementation, newWidget)
childNode = childNode.next
return MIMEText(newWidget.serialize(), "html", "UTF-8")
def generateHtmlPage(self, layout):
return self.generateHtml(layout)
class i(InlineLevelElement):
pass

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -39,7 +38,7 @@ import time
from OpenSSL import SSL
import __init__ as abracadabra
import __init__ as expression
import environs
import html
import logs
@ -91,7 +90,7 @@ class HttpRequestHandlerMixin:
baseEnviron = None # Class variable.
socketCreationTime = None
protocol_version = "HTTP/1.1"
server_version = "Abracadabra/%s" % abracadabra.versionNumber
server_version = "Expression/%s" % expression.versionNumber
sys_version = "Python/%s" % sys.version.split()[0]
def do_GET(self):
@ -105,7 +104,7 @@ class HttpRequestHandlerMixin:
_level = "do_GET",
logger = logger,
)
currentContext = environs.get()
environ = environs.get()
try:
self.application.handleHttpCommand(self)
except IOError:
@ -114,7 +113,7 @@ class HttpRequestHandlerMixin:
except:
logger.exception("An exception occured:")
raise
assert currentContext == environs.get()
assert environ == environs.get()
do_HEAD = do_GET
do_POST = do_GET
@ -148,7 +147,7 @@ class HttpRequestHandlerMixin:
message = """\
From: %(from)s
To: %(to)s
Subject: [%(host)s] Glasnost-XML Talkback
Subject: [%(host)s] Expression Talkback
Url: %(uriScheme)s://%(host)s%(url)s
User-Agent: %(user-agent)s
@ -217,8 +216,10 @@ Client: %(client-ip)s
# We need to save the session before sending response, otherwise, the
# server may receive a new HTTP request before the session is saved.
session = environs.getVar("session")
if session is not None and session.dataHolder.isDirty:
session.dataHolder.save()
if session is not None:
sessionHolder = session.dataHolder
if sessionHolder.isDirty:
sessionHolder.save()
outputHeaders = {}
if time.time() > self.socketCreationTime + 300:
@ -303,8 +304,10 @@ Client: %(client-ip)s
# We need to save the session before sending response, otherwise, the
# server may receive a new HTTP request before the session is saved.
session = environs.getVar("session")
if session is not None and session.dataHolder.isDirty:
session.dataHolder.save()
if session is not None:
sessionHolder = session.dataHolder
if sessionHolder.isDirty:
sessionHolder.save()
message = """Moved Temporarily to "%s".""" % uri
logs.debug(message)
@ -327,8 +330,10 @@ Client: %(client-ip)s
# We need to save the session before sending response, otherwise, the
# server may receive a new HTTP request before the session is saved.
session = environs.getVar("session", default = None)
if session is not None and session.dataHolder.isDirty:
session.dataHolder.save()
if session is not None:
sessionHolder = session.dataHolder
if sessionHolder.isDirty:
sessionHolder.save()
virtualHost = environs.getVar("virtualHost", default = None)
if not virtualHost \
@ -353,7 +358,8 @@ Client: %(client-ip)s
cookieContent = {}
session = environs.getVar("session")
if session is not None:
cookieContent["sessionToken"] = session.dataHolder.localId
sessionHolder = session.dataHolder
cookieContent["sessionToken"] = sessionHolder.localId
for key, value in cookieContent.items():
cookie[key] = value
cookie[key]["path"] = "/"
@ -385,7 +391,7 @@ Client: %(client-ip)s
def version_string(self):
"""Return the server software version string."""
return "%s %s" % (
abracadabra.applicationName, abracadabra.versionNumber)
expression.applicationName, expression.versionNumber)
class HttpRequestHandler(HttpRequestHandlerMixin,

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -76,102 +75,6 @@ def extractUriHostName(location):
return hostName
def getAbsoluteUri(location):
lowerLocation = location.lower()
if lowerLocation.find(":", 0, 10) >= 0:
# Don't touch location if it begins with "http:", "mailto", etc.
return location
else:
# Relative URI, which may or not start with "file://".
# FIXME: This is not the good solution. We need a better way to convert
# file systems path to URI paths.
if lowerLocation.startswith("file://"):
absolutePath = location[len("file://") - 1:]
while len(absolutePath) > 1 and absolutePath[1] == "/":
absolutePath = absolutePath[1:]
else:
absolutePath = getUriAbsolutePath(location)
if absolutePath == "/":
absolutePath = ""
return "%s://%s%s" % (
environs.getVar("uriScheme"), environs.getVar("uriAuthority"),
absolutePath)
def getAbsolutePath(location):
# We assume that location is a relative URI without "file://" prefix.
if location.startswith("//"):
# Relative URI with network path
raise "TODO"
elif location and location[0] == "/":
# Relative URI with absolute path.
return os.path.join(
environs.getVar("virtualHostDirectoryPath"), location[1:])
else:
# Relative URI with relative path.
dataHolder = environs.getVar("currentActionHandler").dataHolder
return os.path.abspath(os.path.join(
dataHolder.directoryAbsolutePath, location))
def getUri(location):
"""Return the best URI to use inside web pages."""
lowerLocation = location.lower()
if lowerLocation.find(":", 0, 10) >= 0:
# Don't touch location if it begins with "http:", "mailto", etc.
return location
else:
# We assume that location is a relative URI whithout "file://" prefix.
uri = getUriAbsolutePath(location)
if not environs.getVar("canUseCookie"):
session = environs.getVar("session")
if session is not None:
uri = appendParameterToUrl(
uri, "sessionToken", session.dataHolder.localId)
return uri
def getUriAbsolutePath(location):
# We assume that location is a relative URI without "file://" prefix.
if location.startswith("//"):
# Relative URI with network path
raise "TODO"
elif location and location[0] == "/":
# Relative URI with absolute path.
absolutePath = environs.getVar("httpScriptDirectoryPath")
if absolutePath[-1] == "/":
return "%s%s" % (absolutePath, location[1:])
else:
return "%s/%s" % (absolutePath, location[1:])
else:
# Relative URI with relative path.
dataHolder = environs.getVar("currentActionHandler").dataHolder
absolutePath = dataHolder.uriDirectoryAbsolutePath
if absolutePath[-1] == "/":
return "%s%s" % (absolutePath, location)
else:
return "%s/%s" % (absolutePath, location)
def getUriInternPath(location):
# We assume that location is a relative URI without "file://" prefix.
if location.startswith("//"):
# Relative URI with network path
raise "TODO"
elif location and location[0] == "/":
# Relative URI with absolute path.
return location
else:
# Relative URI with relative path.
dataHolder = environs.getVar("currentActionHandler").dataHolder
internPath = dataHolder.uriDirectoryInternPath
if internPath[-1] == "/":
return "%s%s" % (internPath, location)
else:
return "%s/%s" % (internPath, location)
def isLocalUri(location):
authority = environs.getVar("uriAuthority")
if "@" in authority:

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or

View File

@ -2,11 +2,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -45,25 +44,26 @@ import libxml2
import libxslt
# Changed by "make install".
abracadabraPythonDirectoryPath = "/usr/local/lib/abracadabra-devel"
sys.path.insert(0, abracadabraPythonDirectoryPath)
expressionPythonDirectoryPath = "/usr/local/lib/expression-devel"
sys.path.insert(0, expressionPythonDirectoryPath)
import abracadabra
import expression
import abracadabra.configurations as configurations
import abracadabra.dataholders as dataholders
import abracadabra.elements as elements
import abracadabra.environs as environs
import abracadabra.faults as faults
import abracadabra.html as html
import abracadabra.http as http
import abracadabra.logs as logs
import abracadabra.locations as locations
import abracadabra.modules as modules
import abracadabra.namespaces as namespaces
import abracadabra.resources as resources
import abracadabra.steps as steps
import abracadabra.xpaths as xpaths
import expression.configurations as configurations
import expression.dataholders as dataholders
import expression.elements as elements
import expression.environs as environs
import expression.faults as faults
import expression.html as html
import expression.http as http
import expression.logs as logs
import expression.locations as locations
import expression.modules as modules
import expression.namespaces as namespaces
import expression.stations as stations
import expression.steps as steps
import expression.stylesheets as stylesheets
import expression.xpaths as xpaths
def goDaemon(nochdir = 0, noclose = 0, user = None, group = None):
@ -135,12 +135,8 @@ class Application(object):
_level = "handleHttpCommand",
canUseCookie = False,
cookie = None,
currentActionHandler = None,
currentStation = None,
currentDirectoryPath = None,
# DataHoldersCache contains only data holders which are slow to
# load or setup (for example: XML files). It is indexed by data
# holders absolute URI.
dataHoldersCache = {},
fieldStorage = None,
httpQuery = None,
httpRequestHandler = httpRequestHandler,
@ -148,6 +144,7 @@ class Application(object):
languageSetInUrl = False,
postedXml = None,
readLanguages = None,
rootStation = None,
session = None,
uriAuthority = httpRequestHandler.headers["Host"],
uriScheme = environs.getVar("httpServer").uriScheme,
@ -179,17 +176,19 @@ class Application(object):
httpInternPath = httpPath[len(httpScriptDirectoryPath):]
# Setup root data holder.
uriStep = steps.UriRootStep(
rootWay = steps.FileSystemRootStep(
None, # No previous step
virtualHost.directoryPath,
virtualHost.systemDirectoryPath)
uriWay = steps.UriRootStep(
None, # No previous step
environs.getVar("uriScheme"),
environs.getVar("uriAuthority"),
environs.getVar("httpScriptDirectoryPath"))
fileSystemStep = steps.FileSystemRootStep(
virtualHost.directoryPath, virtualHost.systemDirectoryPath)
resource = resources.LocalResource(
uriStep, fileSystemStep, fileSystemStep)
rootDataHolder = dataholders.DataHolder(resource)
rootDataHolder = dataholders.DataHolder(rootWay, None, uriWay)
rootDataHolder.setup()
environs.setVar("currentActionHandler", rootDataHolder.actionHandler)
environs.setVar("rootStation", rootDataHolder)
environs.setVar("currentStation", rootDataHolder)
# Get query, headers and form variables.
if httpRequestHandler.headers.typeheader is None:
@ -261,18 +260,15 @@ class Application(object):
canUseCookie = True
session = None
if sessionToken is not None:
sessionsDirectory = dataholders.walkToLocation("/sessions")
try:
session = sessionsDirectory.getItem(sessionToken)
except faults.PathNotFound:
sessionsDirectory = rootDataHolder.walkToLocation("/sessions")
session = sessionsDirectory.getItem(sessionToken)
if session is None:
sessionToken = None
else:
if not sessionTokenInCookie:
# The sessionToken is valid but is not stored in the
# cookie. So, don't try to use the cookie.
canUseCookie = False
logs.debug(
"""Session "%s" for token "%s".""" % (session, sessionToken))
elif not sessionTokenInCookie:
# The sessionToken is valid but is not stored in the
# cookie. So, don't try to use the cookie.
canUseCookie = False
logs.debug("""Session for token "%s".""" % sessionToken)
if canUseCookie:
environs.setVar("canUseCookie", canUseCookie)
user = None
@ -282,19 +278,17 @@ class Application(object):
userLocation = session.userLocation
if userLocation is not None:
try:
user = dataholders.walkToLocation(userLocation)
user = rootDataHolder.walkToLocation(user)
except faults.PathNotFound:
logs.debug(
"""User at location "%s" doesn't exist.""" \
% userLocation)
logs.debug("""User at location "%s" doesn't exist."""
% userLocation)
else:
environs.setVar("user", user)
if user is None:
logs.debug("""User = None at location "%s".""" % userLocation)
else:
logs.debug(
"""User = "%s" at location "%s".""" % (
user.simpleLabel, userLocation))
logs.debug("""User = "%s" at location "%s".""" % (
user.simpleLabel, userLocation))
# Look for the right languages to use for HTTP answer.
languages = []
@ -336,8 +330,10 @@ class Application(object):
httpRequestHandler.outputErrorUnauthorized(path)
finally:
session = environs.getVar("session")
if session is not None and session.dataHolder.isDirty:
session.dataHolder.save()
if session is not None:
sessionHolder = session.dataHolder
if sessionHolder.isDirty:
sessionHolder.save()
finally:
environs.pull(_level = "handleHttpCommand")
@ -363,6 +359,8 @@ class Application(object):
namespaces.xhtml2.name, namespaces.xhtml2.uri)
self.xpathContext.xpathRegisterNs(
namespaces.xsd.name, namespaces.xsd.uri)
self.xpathContext.xpathRegisterNs(
namespaces.xslt.name, namespaces.xslt.uri)
self.xpathContext.xpathRegisterNs(
namespaces.yep.name, namespaces.yep.uri)
xpaths.registerFunctions(self.xpathContext)
@ -374,7 +372,7 @@ class Application(object):
locale.setlocale(locale.LC_COLLATE, (language, None))
except locale.Error:
locale.setlocale(locale.LC_COLLATE, "C")
domains = [abracadabra.applicationName] + (virtualHost.locales or [])
domains = [expression.applicationName] + (virtualHost.locales or [])
localeDirectoryPath = "locale" # FIXME: "/usr/share/locale"
translation = gettext.NullTranslations()
for domain in domains:
@ -408,17 +406,17 @@ def getNewButtonsLayout(ctx):
tctxt = ctxt.transformContext()
insertNode = tctxt.insertNode()
layout = elements.newElement(insertNode)
actionHandler = environs.getVar("currentActionHandler")
dataHolder = actionHandler.dataHolder
station = environs.getVar("currentStation")
dataHolder = station.dataHolder
for namespaceName, elementName \
in modules.getHolderConstructorNamespaceAndElementNames():
actionName = "new-%s-%s" % (namespaceName, elementName)
if not actionHandler.walk([actionName, "exists"]) \
or not actionHandler.walk([actionName, "isAuthorized"]):
if not station.walk([actionName, "exists"]) \
or not station.walk([actionName, "isAuthorized"]):
continue
layout.append(html.a(
_("New %s") % elementName,
class_ = "button", href = dataHolder.getActionUri(actionName)))
_("New %s") % elementName, class_ = "button",
href = dataHolder.getActionUri(actionName)))
return ""
except:
logs.exception(
@ -444,10 +442,14 @@ def getPageLayout(ctx):
tctxt = ctxt.transformContext()
insertNode = tctxt.insertNode()
layout = elements.newElement(insertNode)
environs.getVar("currentActionHandler").fillPageLayout(layout)
htmlPage = environs.getVar("currentHtmlPage")
bodyChildrenNodes = htmlPage.evaluateXpath("/html/body/*")
for node in bodyChildrenNodes:
layout.append(node.copyNode(True))
return ""
except:
logs.exception("""An exception occured in XSLT function "getLayout":""")
logs.exception(
"""An exception occured in XSLT function "getPageLayout":""")
# FIXME: Return an HTTP error code instead of the exception text.
stdout = sys.stdout
stderr = sys.stderr
@ -460,26 +462,15 @@ def getPageLayout(ctx):
libxslt.registerExtModuleFunction(
"getPageLayout", namespaces.yep.uri, getPageLayout)
## def getRelativeUrl(ctx, httpNameNodes):
## return locations.getUriAbsolutePath(libxml2.xmlNode(
## httpNameNodes[0]).content)
## libxslt.registerExtModuleFunction(
## "getRelativeUrl", namespaces.yep.uri, getRelativeUrl)
def getUrl(ctx, *arguments):
# The first argument if it exists is the location (current location used by
# default).
# The other arguments are the URL parameters.
if not arguments:
location = environs.getVar(
"currentActionHandler").dataHolder.uriInternPath
url = locations.getUri(location)
url = environs.getVar("currentStation").uri
else:
location = arguments[0]
url = locations.getUri(location)
url = environs.getVar("currentStation").constructUri(location)
for i in range(1, len(arguments), 2):
url = locations.appendParameterToUrl(
url, arguments[i], arguments[i + 1])
@ -489,10 +480,11 @@ libxslt.registerExtModuleFunction("getUrl", namespaces.yep.uri, getUrl)
def getUrlInternPath(ctx, location = None):
station = environs.getVar("currentStation")
if location is None:
path = environs.getVar("currentActionHandler").dataHolder.uriInternPath
path = station.uriInternPath
else:
path = locations.getUriInternPath(location)
path = station.constructUriInternPath(location)
return path
libxslt.registerExtModuleFunction(
@ -566,11 +558,11 @@ if __name__ == "__main__":
environs.setVar("application", application)
# Build configuration from configuration file.
fileSystemStep = steps.FileSystemRootStep(
configurationHolderWay = steps.FileSystemRootStep(
None, # No previous step
os.path.abspath(options.configurationFilePath))
resource = resources.LocalResource(None, fileSystemStep, fileSystemStep)
configurationHolder = dataholders.DataHolder(
resource, mimeType = "text/xml")
configurationHolderWay, mimeType = "text/xml")
configurationHolder.setup()
configuration = configurationHolder.rootElement
environs.setVar("configuration", configuration)

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -51,8 +50,9 @@ def getUri(name):
ev = Namespace("ev", "http://www.w3.org/2001/xml-events")
html = Namespace("html", "http://www.w3.org/1999/xhtml")
mail = Namespace("mail", "http://glasnost.entrouvert.org/namespaces/email/0.0")
mail = Namespace("mail", "http://www.entrouvert.org/namespaces/email/0.0")
xforms = Namespace("xforms", "http://www.w3.org/2002/xforms")
xhtml2 = Namespace("xhtml2", "http://www.w3.org/2002/06/xhtml2")
xsd = Namespace("xsd", "http://www.w3.org/2001/XMLSchema")
yep = Namespace("yep", "http://abracadabra.entrouvert.org/0.0")
xslt = Namespace("xslt", "http://www.w3.org/1999/XSL/Transform")
yep = Namespace("yep", "http://www.entrouvert.org/namespaces/expression/0.0")

84
src/core/nodes.py Normal file
View File

@ -0,0 +1,84 @@
# -*- coding: UTF-8 -*-
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""XML Nodes Module"""
import types
import libxml2
import namespaces
class NodeWrapper(object):
node = None
def __init__(self, node):
assert node is not None
self.node = node
def append(self, item):
assert type(item) not in (types.ListType, types.TupleType), \
"Wrong item = %s (of type %s)" % (str(item), str(type(item)))
if item is None:
return
if isinstance(item, NodeWrapper):
item = item.node
if isinstance(item, libxml2.xmlCore):
self.node.addChild(item)
try:
namespace = item.ns()
except libxml2.treeError:
pass
else:
if namespace is None:
namespaceUri = namespaces.html.uri
namespace = item.newNs(namespaceUri, None)
item.setNs(namespace)
#~ if isinstance(item, elements.Element):
#~ itemNode = item.node
#~ self.node.addChild(itemNode)
#~ dataHolder = self.dataHolder
#~ if dataHolder is None:
#~ if item.namespaceUri == self.namespaceUri:
#~ itemNode.setNs(None)
#~ else:
#~ raise "FIXME: To do: set itemNode namespace"
#~ else:
#~ namespace = self.node.searchNsByHref(
#~ dataHolder.node, item.namespaceUri)
#~ if namespace is None:
#~ raise "FIXME: To do: set itemNode namespace"
#~ else:
#~ itemNode.setNs(namespace)
#~ elif isinstance(item, libxml2.xmlCore):
#~ self.node.addChild(item)
elif isinstance(item, unicode):
self.node.addContent(item.encode("UTF-8"))
else:
self.node.addContent(item)
def serialize(self):
return self.node.serialize()

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -38,6 +37,7 @@ import locations
import logs
import modules
import namespaces
import stations
class Session(elements.Element):
@ -155,6 +155,8 @@ class SessionHolder(dataholders.XmlHolder):
class Sessions(directories.Directory):
def getItem(self, sessionToken):
session = directories.Directory.getItem(self, sessionToken)
if session is None:
return None
# FIXME: Remove old sessions.
httpRequestHandler = environs.getVar("httpRequestHandler")
clientIpAddress = httpRequestHandler.client_address[0]
@ -178,16 +180,17 @@ def createSessionIfNeeded(nextUrl):
session = environs.getVar("session")
if session is None:
sessionsDirectory = dataholders.walkToLocation("/sessions")
sessionsDirectory = self.walkToLocation("/sessions")
sessionHolderConstructor = modules.getHolderConstructor(
namespaces.yep.uri, "session")
sessionHolder = sessionHolderConstructor(sessionsDirectory)
session = sessionHolder.actionHandler
sessionHolder = sessionHolderConstructor(
sessionsDirectory)
session = sessionHolder.walk([])
baseEnviron = environs.get(_level = "handleHttpCommand")
baseEnviron.setVar("session", session)
canUseCookie = environs.getVar("canUseCookie")
if canUseCookie:
url = locations.getUriAbsolutePath("/test-cookie")
url = self.constructUriAbsolutePath("/test-cookie")
url = locations.appendParameterToUrl(
url, "sessionToken", sessionHolder.localId)
url = locations.appendParameterToUrl(url, "nextUrl", nextUrl)
@ -216,4 +219,5 @@ modules.registerElementClass(namespaces.yep.uri, "sessions", Sessions)
modules.registerHolderClass(namespaces.yep.uri, "session", SessionHolder)
modules.registerHolderConstructor(namespaces.yep.uri, "session", newSessionHolder)
modules.registerHolderConstructor(
namespaces.yep.uri, "session", newSessionHolder)

548
src/core/stations.py Normal file
View File

@ -0,0 +1,548 @@
# -*- coding: UTF-8 -*-
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Stations Module"""
import libxslt
import environs
import faults
import locations
import logs
class AbstractStation(object):
_hierarchicalWay = None
_internalWay = None
_uriWay = None
isRemote = False
methodActionNames = {
"doHttpRequest": "doHttpRequest",
"submit": "doHttpPost",
"source": "doHttpSource",
"styled": "doHttpStyled",
"unstyled": "doHttpUnstyled",
}
remoteUri = None
def __init__(self, internalWay = None, hierarchicalWay = None,
uriWay = None, isRemote = False, remoteUri = None):
if isRemote:
assert internalWay is None
assert hierarchicalWay is None
assert uriWay is None
assert remoteUri
self.isRemote = isRemote
self.remoteUri = remoteUri
else:
assert remoteUri is None
if internalWay is not None:
self.internalWay = internalWay
if hierarchicalWay is not None:
self.hierarchicalWay = hierarchicalWay
if uriWay is not None:
self.uriWay = uriWay
def constructAbsoluteUri(self, location):
lowerLocation = location.lower()
if lowerLocation.find(":", 0, 10) >= 0:
# Don't touch location if it begins with "http:", "mailto", etc.
return location
else:
# Relative URI, which may or not start with "file://".
# FIXME: This is not the good solution. We need a better way to convert
# file systems path to URI paths.
if lowerLocation.startswith("file://"):
absolutePath = location[len("file://") - 1:]
while len(absolutePath) > 1 and absolutePath[1] == "/":
absolutePath = absolutePath[1:]
else:
absolutePath = self.constructUriAbsolutePath(location)
if absolutePath == "/":
absolutePath = ""
return "%s://%s%s" % (
environs.getVar("uriScheme"), environs.getVar("uriAuthority"),
absolutePath)
def constructUri(self, location):
"""Return the best URI to use inside web pages."""
lowerLocation = location.lower()
if lowerLocation.find(":", 0, 10) >= 0:
# Don't touch location if it begins with "http:", "mailto", etc.
return location
else:
# We assume that location is a relative URI whithout "file://" prefix.
uri = self.constructUriAbsolutePath(location)
if not environs.getVar("canUseCookie"):
session = environs.getVar("session")
if session is not None:
uri = locations.appendParameterToUrl(
uri, "sessionToken", session.dataHolder.localId)
return uri
def constructUriAbsolutePath(self, location):
# Assume that location is a relative URI without "file://" prefix.
if location.startswith("//"):
# Relative URI with network path
raise "TODO"
elif location and location[0] == "/":
# Relative URI with absolute path.
absolutePath = environs.getVar("httpScriptDirectoryPath")
if absolutePath[-1] == "/":
return "%s%s" % (absolutePath, location[1:])
else:
return "%s/%s" % (absolutePath, location[1:])
else:
# Relative URI with relative path.
absolutePath = self.dataHolder.uriDirectoryAbsolutePath
if absolutePath[-1] == "/":
return "%s%s" % (absolutePath, location)
else:
return "%s/%s" % (absolutePath, location)
def constructUriInternPath(self, location):
# We assume that location is a relative URI without "file://" prefix.
if location.startswith("//"):
# Relative URI with network path
raise "TODO"
elif location and location[0] == "/":
# Relative URI with absolute path.
return location
else:
# Relative URI with relative path.
internPath = self.dataHolder.uriDirectoryInternPath
if internPath[-1] == "/":
return "%s%s" % (internPath, location)
else:
return "%s/%s" % (internPath, location)
def doHttpPost(self, station):
raise "FIXME: TODO"
def doHttpRequest(self, station):
return self.doHttpStyled(station)
def doHttpSource(self, station):
self.outputHttpSource()
return Terminus()
def doHttpStyled(self, station):
stylesheet = self.dataHolder.stylesheet
if stylesheet is None:
self.outputHttpUnstyled()
else:
self.outputHttpStyled(stylesheet)
return Terminus()
def doHttpUnstyled(self, station):
self.outputHttpUnstyled()
return Terminus()
def evaluate(self, httpNames):
return self, httpNames
def generateHtml(self, layout):
logs.debug("generateHtml: No HTML generation for %s." % self)
return False
def generateHtmlPage(self, layout):
"""Layout a complete HTML page."""
import html
bodyLayout = html.body()
layout.append(html.html(bodyLayout))
self.generateHtml(bodyLayout)
return True
def getAbsolutePath(self):
hierarchicalWay = self.hierarchicalWay
if hierarchicalWay is None:
return self.internalWay.absolutePath
else:
return hierarchicalWay.absolutePath
def getAbsoluteUri(self):
if self.isRemote:
return self.constructAbsoluteUri(self.remoteUri)
else:
uriWay = self.uriWay
if uriWay is None:
hierarchicalWay = self.hierarchicalWay
if hierarchicalWay is None:
return self.internalWay.absoluteUri
else:
return hierarchicalWay.absoluteUri
else:
return uriWay.absoluteUri
def getActionUri(self, action = None):
uri = self.uriAbsolutePath
if action:
if uri[-1] == "/":
uri = "%s%s" % (uri, action)
else:
uri = "%s/%s" % (uri, action)
if not environs.getVar("canUseCookie"):
session = environs.getVar("session")
if session is not None:
uri = locations.appendParameterToUrl(
uri, "sessionToken", session.dataHolder.localId)
return uri
def getDataHolder(self):
import dataholders
if isinstance(self, dataholders.DataHolder):
return self
else:
return self.parent.dataHolder
def getDirectoryAbsolutePath(self):
return self.parent.absolutePath
def getHierarchicalWay(self):
return self._hierarchicalWay
def getInternalWay(self):
return self._internalWay
def getInternPath(self):
hierarchicalWay = self.hierarchicalWay
if hierarchicalWay is None:
return self.internalWay.internPath
else:
return hierarchicalWay.internPath
def getParent(self):
hierarchicalWay = self.hierarchicalWay
if hierarchicalWay is None:
return self.previous
hierarchicalWayPrevious = hierarchicalWay.previous
if hierarchicalWayPrevious is None:
return None
return hierarchicalWayPrevious.station
def getPrevious(self):
internalWay = self.internalWay
if internalWay is None:
return None
internalWayPrevious = internalWay.previous
if internalWayPrevious is None:
return None
return internalWayPrevious.station
def getSubPathInternUri(self, subPath):
assert not subPath or subPath[0] != "/"
uri = self.uriInternPath
if subPath is not None:
if uri[-1] == "/":
uri = "%s%s" % (uri, subPath)
else:
uri = "%s/%s" % (uri, subPath)
return uri
def getSystemAbsolutePath(self):
hierarchicalWay = self.hierarchicalWay
if hierarchicalWay is None:
return self.internalWay.systemAbsolutePath
else:
return hierarchicalWay.systemAbsolutePath
def getUri(self):
uri = self.uriAbsolutePath
if not environs.getVar("canUseCookie"):
session = environs.getVar("session")
if session is not None:
uri = locations.appendParameterToUrl(
uri, "sessionToken", session.dataHolder.localId)
return uri
def getUriAbsolutePath(self):
uriWay = self.uriWay
if uriWay is None:
return self.internalWay.uriAbsolutePath
else:
return uriWay.uriAbsolutePath
def getUriDirectoryAbsolutePath(self):
return self.uriParent.uriAbsolutePath
def getUriDirectoryInternPath(self):
return self.uriParent.uriInternPath
def getUriFirstCommonAncestor(self, uriAbsolutePath):
return self.uriWay.getUriFirstCommonAncestor(uriAbsolutePath).station
def getUriInternPath(self):
uriWay = self.uriWay
if uriWay is None:
return self.internalWay.uriInternPath
else:
return uriWay.uriInternPath
def getUriParent(self):
uriWay = self.uriWay
if uriWay is None:
return None
uriWayPrevious = uriWay.previous
if uriWayPrevious is None:
return None
return uriWayPrevious.station
def getUriWay(self):
uriWay = self._uriWay
if uriWay is not None:
return uriWay
internalWayPrevious = self.internalWay.previous
if internalWayPrevious is None:
return None
return internalWayPrevious.station.uriWay
def isAccessAuthorized(self):
return self.isContentAccessAuthorized("access")
def isContentAccessAuthorized(self, contentName):
raise NotImplementedError(
"Method isContentAccessAuthorized not implemented for %s" % self)
def itemDestroyed(self, item):
"""Called before an item (hierarchical) is destroyed"""
pass
def itemRenamed(self, item, itemOldLocalId):
"""Called after an item (hierarchical) is renamed"""
pass
def outputHttpSource(self):
raise NotImplementedError(
"Method outputHttpSource not implemented for %s" % self)
def outputHttpStyled(self, stylesheet):
#~ libxml2.lineNumbersDefault(1)
#~ libxml2.substituteEntitiesDefault(1)
import documents
htmlPage = documents.newTemporaryDocument()
self.generateHtmlPage(htmlPage)
stylesheetHolder = stylesheet.prototype.dataHolder
stylesheetStyle = libxslt.parseStylesheetDoc(stylesheetHolder.node)
environs.push(_level = "doHttpRequest",
currentHtmlPage = htmlPage,
currentStation = self)
try:
styledDoc = stylesheetStyle.applyStylesheet(htmlPage.node, None)
finally:
environs.pull(_level = "doHttpRequest")
data = stylesheetStyle.saveResultToString(styledDoc)
styledDoc.freeDoc()
stylesheetStyle.freeStylesheet()
environs.getVar("httpRequestHandler").outputData(
data, contentLocation = self.uriAbsolutePath,
mimeType = "text/html")
def outputHttpUnstyled(self):
import documents
import html
htmlPage = documents.newTemporaryDocument()
self.generateHtmlPage(htmlPage)
data = htmlPage.serialize()
environs.getVar("httpRequestHandler").outputData(
data, contentLocation = self.uriAbsolutePath,
mimeType = "text/html")
def setHierarchicalWay(self, hierarchicalWay):
assert hierarchicalWay.station is None \
or hierarchicalWay.station == self
self._hierarchicalWay = hierarchicalWay
hierarchicalWay.station = self
def setInternalWay(self, internalWay):
assert internalWay.station is None or internalWay.station == self
self._internalWay = internalWay
internalWay.station = self
def setUriWay(self, uriWay):
assert uriWay.station is None or uriWay.station == self
self._uriWay = uriWay
uriWay.station = self
def walk(self, httpNames):
evaluation, httpNamesAfterEvaluation = self.evaluate(httpNames)
if not isinstance(evaluation, AbstractStation):
if not httpNamesAfterEvaluation:
return evaluation
raise Exception("""\
Invalid value (= "%s") & httpNames (= "%s") after evaluation of object "%s"\
with httpNames "%s".""" % (
evaluation, httpNamesAfterEvaluation, self, httpNames))
if evaluation != self and not evaluation.isAccessAuthorized():
if httpNamesAfterEvaluation \
and httpNamesAfterEvaluation[-1] == "isAuthorized":
return False
raise faults.PathUnauthorized("/".join(httpNames))
content, remainingHttpNames = evaluation.walkToContent(
httpNamesAfterEvaluation)
if content is None:
if httpNamesAfterEvaluation[-1] == "exists":
return False
raise faults.PathNotFound("/".join(httpNames))
if content != evaluation and not content.isAccessAuthorized():
logs.debug(
"walk: Access unauthorized for content %s of evaluation %s."
% (content, evaluation))
if remainingHttpNames and remainingHttpNames[-1] == "isAuthorized":
return False
raise faults.PathUnauthorized("/".join(httpNames))
if content == self and remainingHttpNames == httpNames:
if remainingHttpNames:
raise Exception(
"Infinite loop during walk inside %s with %s." % (
content, remainingHttpNames))
# The walk doesn't move anymore and there isn't any HTTP name
# left. We are arrived.
return content
return content.walk(remainingHttpNames)
def walkToAction(self, httpNames):
# The actions "exists", "isAuthorized" & "source" are special and are
# not handled in this method.
if not httpNames:
return self, httpNames
actionName = httpNames[0]
if actionName not in self.methodActionNames:
return None, httpNames
try:
method = getattr(self, self.methodActionNames[actionName])
except AttributeError:
return None, httpNames
return FunctionStation(self, actionName, method), httpNames[1:]
def walkToContent(self, httpNames):
item, remainingHttpNames = self.walkToItem(httpNames)
if item is not None:
if item != self or remainingHttpNames != httpNames:
return item, remainingHttpNames
action, remainingHttpNames = self.walkToAction(httpNames)
if action is not None:
return action, remainingHttpNames
return None, httpNames
def walkToItem(self, httpNames):
if not httpNames:
return self, httpNames
return None, httpNames
def walkToLocation(self, location):
if locations.isLocalUri(location):
rootStation = environs.getVar("rootStation")
uriInternPath = self.constructUriInternPath(location)
return rootStation.walk(
[name for name in uriInternPath.split("/") if name])
else:
locationCore, locationExtension = os.path.splitext(location)
mimeType = None
if locationExtension in mimeTypes:
mimeType = mimeTypes[locationExtension]
dataHolder = DataHolder(
isRemote = True, remoteUri = location, mimeType = mimeType)
dataHolder.setup()
return dataHolder.walk([])
absolutePath = property(getAbsolutePath)
absoluteUri = property(getAbsoluteUri)
dataHolder = property(getDataHolder)
directoryAbsolutePath = property(getDirectoryAbsolutePath)
hierarchicalWay = property(getHierarchicalWay, setHierarchicalWay)
internalWay = property(getInternalWay, setInternalWay)
internPath = property(getInternPath)
absolutePath = property(getAbsolutePath)
parent = property(getParent)
previous = property(getPrevious)
systemAbsolutePath = property(getSystemAbsolutePath)
uri = property(getUri)
uriAbsolutePath = property(getUriAbsolutePath)
uriDirectoryAbsolutePath = property(getUriDirectoryAbsolutePath)
uriDirectoryInternPath = property(getUriDirectoryInternPath)
uriInternPath = property(getUriInternPath)
uriParent = property(getUriParent)
uriWay = property(getUriWay, setUriWay)
class AbstractImplementation(AbstractStation):
prototype = None
specimen = None
def __init__(self, prototype, specimen, internalWay = None, uriWay = None):
AbstractStation.__init__(
self, internalWay = internalWay, uriWay = uriWay)
if prototype is not None:
self.prototype = prototype
assert specimen
self.specimen = specimen
def getHierarchicalWay(self):
return self.prototype.hierarchicalWay
def isContentAccessAuthorized(self, contentName):
return self.dataHolder.isContentAccessAuthorized(contentName)
hierarchicalWay = property(getHierarchicalWay)
class FunctionStation(AbstractStation):
actionName = None
container = None
function = None
def __init__(self, container, actionName, function):
self.container = container
self.actionName = actionName
self.function = function
def __repr__(self):
return "FunctionStation(%s, %s, %s)" % (
self.container, self.actionName, self.function)
def evaluate(self, httpNames):
result = self.function(self)
return result, httpNames
def isAccessAuthorized(self):
return self.container.isContentAccessAuthorized(self.actionName)
class Terminus(AbstractStation):
methodActionNames = AbstractStation.methodActionNames.copy()
methodActionNames.update({
"doHttpRequest": "doHttpRequest",
})
def doHttpRequest(self, station):
return None
def isAccessAuthorized(self):
return True
def isContentAccessAuthorized(self, contentName):
return True

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -26,46 +25,101 @@
"""Trees & Graphs Walking Steps Module"""
import copy
import os
class AbstractStep(object):
absolutePath = None
resource = None
systemAbsolutePath = None
previous = None
station = None
def __init__(self, previous):
if previous is not None:
self.previous = previous
def duplicate(self):
new = copy.copy(self)
if new.station is not None:
del new.station
return new
def getAbsolutePath(self):
if self.previous is None:
raise NotImplementedError
return self.previous.station.absolutePath
def getAbsoluteUri(self):
if self.previous is None:
raise NotImplementedError
return self.previous.station.absoluteUri
def getInternPath(self):
if self.previous is None:
raise NotImplementedError
return self.previous.station.internPath
def getSystemAbsolutePath(self):
if self.previous is None:
raise NotImplementedError
return self.previous.station.systemAbsolutePath
def getUriAbsolutePath(self):
if self.previous is None:
raise NotImplementedError
return self.previous.station.uriAbsolutePath
def getUriInternPath(self):
if self.previous is None:
raise NotImplementedError
return self.previous.station.uriInternPath
absolutePath = property(getAbsolutePath)
absoluteUri = property(getAbsoluteUri)
internPath = property(getInternPath)
systemAbsolutePath = property(getSystemAbsolutePath)
uriAbsolutePath = property(getUriAbsolutePath)
uriInternPath = property(getUriInternPath)
# File System Steps
class AbstractFileSystemStep(AbstractStep):
name = None
def __init__(self, name):
assert name
self.name = name
def getAbsolutePath(self):
raise NotImplementedError
def getAbsoluteUri(self):
return "file:/%s" % self.absolutePath
def getInternPath(self):
raise NotImplementedError
def getSystemAbsolutePath(self):
raise NotImplementedError
absolutePath = property(getAbsolutePath)
absoluteUri = property(getAbsoluteUri)
internPath = property(getInternPath)
systemAbsolutePath = property(getSystemAbsolutePath)
class FileSystemRootStep(AbstractFileSystemStep):
parent = None
previous = None
internPath = "/"
name = None # Constant
path = None
systemPath = None
def __init__(self, path, systemPath = None):
def __init__(self, previous, path, systemPath = None):
AbstractFileSystemStep.__init__(self, previous)
assert path and path[0] == "/", "Wrong path = %s" % path
AbstractFileSystemStep.__init__(self, path)
self.path = path
if systemPath is not None:
assert systemPath and systemPath[0] == "/", \
"Wrong system path = %s" % systemPath
self.systemPath = systemPath
def getAbsolutePath(self):
return self.name
return self.path
def getSystemAbsolutePath(self):
if self.systemPath is None:
@ -77,74 +131,87 @@ class FileSystemRootStep(AbstractFileSystemStep):
systemAbsolutePath = property(getSystemAbsolutePath)
class FileSystemHierarchicalStep(AbstractFileSystemStep):
parent = None
def __init__(self, parent, name):
assert parent # Use FileSystemRootStep for first step.
self.parent = parent
assert name and "/" not in name
AbstractFileSystemStep.__init__(self, name)
def getAbsolutePath(self):
return os.path.join(self.parent.absolutePath, self.name)
def getSystemAbsolutePath(self):
return os.path.join(self.parent.systemAbsolutePath, self.name)
absolutePath = property(getAbsolutePath)
systemAbsolutePath = property(getSystemAbsolutePath)
class FileSystemStep(AbstractFileSystemStep):
"""A not always hierarchical file system step.
Name may be "../../x" or "/x/y" or "x/y" or...
"""
previous = None
name = None
def __init__(self, previous, name):
assert previous # Use FileSystemRootStep for first step.
self.previous = previous
AbstractFileSystemStep.__init__(self, name)
AbstractFileSystemStep.__init__(self, previous)
assert name
self.name = name
def getAbsolutePath(self):
return os.path.abspath(os.path.join(
self.previous.absolutePath, self.name))
self.previous.station.absolutePath, self.name))
def getInternPath(self):
return os.path.abspath(os.path.join(
self.previous.station.internPath, self.name))
def getSystemAbsolutePath(self):
return os.path.abspath(os.path.join(
self.previous.systemAbsolutePath, self.name))
self.previous.station.systemAbsolutePath, self.name))
absolutePath = property(getAbsolutePath)
internPath = property(getInternPath)
systemAbsolutePath = property(getSystemAbsolutePath)
# HTML Steps
class AbstractHtmlStep(AbstractStep):
pass
class HtmlStep(AbstractHtmlStep):
pass
# URI Steps
class AbstractUriStep(AbstractStep):
parent = None
def getAbsolutePath(self):
raise NotImplementedError
def getAbsoluteUri(self):
raise NotImplementedError
def getInternPath(self):
raise NotImplementedError
def getUriFirstCommonAncestor(self, absolutePath):
raise NotImplementedError
absolutePath = property(getAbsolutePath)
absoluteUri = property(getAbsoluteUri)
internPath = property(getInternPath)
class UriRootStep(AbstractUriStep):
authority = None
internPath = "/"
scheme = None
uriAbsolutePath = None
uriInternPath = "/"
def __init__(self, scheme, authority, absolutePath = None):
def __init__(self, previous, scheme, authority, uriAbsolutePath = None):
AbstractUriStep.__init__(self, previous)
# TODO: Handle other URI schemes.
assert scheme in ("http", "https")
self.scheme = scheme
assert authority and "/" not in authority
self.authority = authority
if absolutePath is None:
self.absolutePath = "/"
if uriAbsolutePath is None:
self.uriAbsolutePath = "/"
else:
while len(absolutePath) > 1 and absolutePath[-1] == "/":
absolutePath = absolutePath[:-1]
self.absolutePath = absolutePath
while len(uriAbsolutePath) > 1 and uriAbsolutePath[-1] == "/":
uriAbsolutePath = uriAbsolutePath[:-1]
self.uriAbsolutePath = uriAbsolutePath
def getAbsoluteUri(self):
absolutePath = self.absolutePath
@ -162,34 +229,101 @@ class UriRootStep(AbstractUriStep):
class UriStep(AbstractUriStep):
name = None
def __init__(self, parent, name):
assert parent # Use UriRootStep for URI first step.
self.parent = parent
def __init__(self, previous, name):
AbstractUriStep.__init__(self, previous)
assert name and "/" not in name
self.name = name
def getAbsolutePath(self):
absolutePath = self.parent.absolutePath
if absolutePath[-1] == "/":
return "%s%s" % (absolutePath, self.name)
else:
return "%s/%s" % (absolutePath, self.name)
def getAbsoluteUri(self):
return "%s/%s" % (self.parent.absoluteUri, self.name)
return "%s/%s" % (self.previous.station.absoluteUri, self.name)
def getInternPath(self):
internPath = self.parent.internPath
if internPath[-1] == "/":
return "%s%s" % (internPath, self.name)
def getUriAbsolutePath(self):
uriAbsolutePath = self.previous.station.uriAbsolutePath
if uriAbsolutePath[-1] == "/":
return "%s%s" % (uriAbsolutePath, self.name)
else:
return "%s/%s" % (internPath, self.name)
return "%s/%s" % (uriAbsolutePath, self.name)
def getUriFirstCommonAncestor(self, absolutePath):
if not absolutePath.startswith(self.absolutePath):
return self.parent.getUriFirstCommonAncestor(absolutePath)
return self.previous.station.getUriFirstCommonAncestor(absolutePath)
return self
absolutePath = property(getAbsolutePath)
def getUriInternPath(self):
uriInternPath = self.previous.station.uriInternPath
if uriInternPath[-1] == "/":
return "%s%s" % (uriInternPath, self.name)
else:
return "%s/%s" % (uriInternPath, self.name)
absoluteUri = property(getAbsoluteUri)
internPath = property(getInternPath)
uriAbsolutePath = property(getUriAbsolutePath)
uriInternPath = property(getUriInternPath)
# XForms Steps
class AbstractXformsStep(AbstractStep):
pass
class XformsModelStep(AbstractXformsStep):
pass
class XformsStep(AbstractXformsStep):
pass
# XML Steps
class AbstractXmlStep(AbstractStep):
pass
class XmlRootElementStep(AbstractXmlStep):
pass
class XmlAttributeStep(AbstractXmlStep):
pass
class XmlDescriptionStep(AbstractXmlStep):
pass
class XmlElementStep(AbstractXmlStep):
pass
class XmlPageStep(AbstractXmlStep):
pass
class XmlReferenceStep(AbstractXmlStep):
"""A XmlReferenceStep is used to access a XML element refered by another
element (for exemple with a XForms "ref" attribute)."""
pass
class XmlSchemasStep(AbstractXmlStep):
pass
class XmlSchemaStep(AbstractXmlStep):
pass
class XmlSourceStep(AbstractXmlStep):
"""A XmlReferenceStep is used to access a XML file refered by a XML
element (for exemple with a XForms "src" attribute)."""
pass
class XmlStylesheetStep(AbstractXmlStep):
pass

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -175,7 +174,7 @@ def makePassword(
def simplify(s):
# We replace " " with "-" instead of "_" because this is better for Google
# indexing.
# We also replace "." with "-" because of Glasnost-XML current limitations
# We also replace "." with "-" because of Expression current limitations
# for handling file name extensions.
return latin1_to_ascii(s).lower().strip().replace(" ", "-").replace(
"'", "").replace('"', "").replace(".", "-")

43
src/core/stylesheets.py Normal file
View File

@ -0,0 +1,43 @@
# -*- coding: UTF-8 -*-
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""XSLT module"""
import elements
import modules
import namespaces
import stations
import steps
class Stylesheet(elements.Element):
pass
class StylesheetImplementation(stations.AbstractImplementation):
pass
modules.registerElementClass(namespaces.xslt.uri, "stylesheet", Stylesheet)

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -33,24 +32,6 @@ import elements
class WidgetMixin(object):
_inForm = False
_readOnly = False
_relevant = True
def generateHtml(self, layout):
raise NotImplementedError
def getChildInstanceDataXpath(self):
return self.instanceDataXpath
def getInstanceDataXpath(self):
return self.parent.childInstanceDataXpath
def getModelId(self):
if self.parent is None:
return None
return self.parent.modelId
def generatePlainText(self):
layout = []
childNode = self.node.children
@ -62,53 +43,48 @@ class WidgetMixin(object):
layout.append(childNode.content.decode("UTF-8"))
childNode = childNode.next
continue
element = elements.newElement(childNode, parent = self)
element = self.newElement(childNode)
layout.append(element.generatePlainText())
childNode = childNode.next
return u"".join(layout)
def isInForm(self):
if self._inForm:
return True
def getBind(self, modelImplementation):
parent = self.parent
if parent is None:
return False
return parent.inForm
return None
return parent.getBind(modelImplementation)
def isReadOnly(self):
if self._readOnly:
return True
def getChildInstanceDataXpath(self, modelImplementation):
return self.getInstanceDataXpath(modelImplementation)
def getInstanceDataXpath(self, modelImplementation):
parent = self.parent
if parent is None:
return False
return parent.readOnly
return ""
else:
return self.parent.getChildInstanceDataXpath(modelImplementation)
def isRelevant(self):
if not self._relevant:
return False
parent = self.parent
if parent is None:
return True
return parent.relevant
def getModel(self, implementation):
return self.getModelImplementation(implementation).prototype
def setInForm(self, inForm):
self._inForm = inForm
def getModelImplementation(self, implementation):
modelId = self.modelId
if modelId is not None and implementation.xformsModelsById is not None \
and modelId in implementation.xformsModelsById:
modelImplementation = implementation.xformsModelsById[modelId]
else:
modelImplementation = implementation.xformsDefaultModel
return modelImplementation
def setReadOnly(self, readOnly):
self._readOnly = readOnly
def setRelevant(self, relevant):
self._relevant = relevant
def getModelId(self):
if self.parent is None:
return None
return self.parent.modelId
def submit(self):
widgetNodes = self.evaluateXpath("*")
for widgetNode in widgetNodes:
widget = elements.newElement(widgetNode, parent = self)
widget = self.newElement(widgetNode)
widget.submit()
childInstanceDataXpath = property(getChildInstanceDataXpath)
inForm = property(isInForm, setInForm)
instanceDataXpath = property(getInstanceDataXpath)
modelId = property(getModelId)
readOnly = property(isReadOnly, setReadOnly)
relevant = property(isRelevant, setRelevant)

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -37,11 +36,30 @@ import logs
import modules
import namespaces
import parsers
import stations
import steps
class Schema(elements.Element):
includeLocations = None
def buildXformsModelImplementation(self, implementation):
if implementation.schemas is None:
schemasInternalWay = steps.XmlSchemasStep(
implementation.internalWay)
implementationUriWay = implementation.uriWay
if implementationUriWay is None:
schemasUriWay = None
else:
schemasUriWay = steps.UriStep(implementationUriWay, "schemas")
implementation.schemas = SchemasImplementation(
implementation.specimen, internalWay = schemasInternalWay,
uriWay = schemasUriWay)
schemasImplementation = implementation.schemas
if schemasImplementation.schemas is None:
schemasImplementation.schemas = []
schemasImplementation.schemas.append(self)
def getAttributeInNodeType(self, node, name):
attributeNode = self.getAttributeNodeInNode(node, name)
if attributeNode is None:
@ -65,7 +83,7 @@ class Schema(elements.Element):
if not typeNodes:
return None
typeNode = typeNodes[0]
return newType(typeNode, dataHolder = self)
return newType(typeNode, parent = self)
def getElementInNodeType(self, node, name):
elementNode = self.getElementNodeInNode(node, name)
@ -90,38 +108,39 @@ class Schema(elements.Element):
if not typeNodes:
return None
typeNode = typeNodes[0]
return newType(typeNode, dataHolder = self)
return newType(typeNode, parent = self)
def getGlobalElementNode(self, name, scannedSchemaLocations = None):
if scannedSchemaLocations is None:
scannedSchemaLocations = []
elif self in scannedSchemaLocations:
def getGlobalElementNode(self, name, scannedSchemas = None):
if scannedSchemas is None:
scannedSchemas = []
elif self in scannedSchemas:
return None
scannedSchemaLocations.append(self)
scannedSchemas.append(self)
elementNode = self.getElementNodeInNode(self.node, name)
if elementNode is not None:
return elementNode
if self.includeLocations:
for includeLocation in self.includeLocations:
includeSchema = dataholders.walkToLocation(includeLocation)
includeSchema = self.walkToLocation(includeLocation)
elementNode = includeSchema.getGlobalElementNode(
name, scannedSchemaLocations = scannedSchemaLocations)
name, scannedSchemas = scannedSchemas)
if elementNode is not None:
return elementNode
return None
def getGlobalElementType(self, name):
elementNode = self.getGlobalElementNode(name)
def getGlobalElementType(self, name, scannedSchemas = None):
elementNode = self.getGlobalElementNode(
name, scannedSchemas = scannedSchemas)
if elementNode is None:
return None
return self.getElementNodeType(elementNode)
def getGlobalType(self, name, scannedSchemaLocations = None):
if scannedSchemaLocations is None:
scannedSchemaLocations = []
elif self in scannedSchemaLocations:
def getGlobalType(self, name, scannedSchemas = None):
if scannedSchemas is None:
scannedSchemas = []
elif self in scannedSchemas:
return None
scannedSchemaLocations.append(self)
scannedSchemas.append(self)
# FIXME.
if name.startswith("xsd:"):
@ -143,9 +162,9 @@ class Schema(elements.Element):
return globalType
if self.includeLocations:
for includeLocation in self.includeLocations:
includeSchema = dataholders.walkToLocation(includeLocation)
includeSchema = self.walkToLocation(includeLocation)
globalType = includeSchema.getGlobalType(
name, scannedSchemaLocations = scannedSchemaLocations)
name, scannedSchemas = scannedSchemas)
if globalType is not None:
return globalType
return None
@ -155,7 +174,7 @@ class Schema(elements.Element):
if not typeNodes:
return None
typeNode = typeNodes[0]
return newType(typeNode, dataHolder = self)
return newType(typeNode, parent = self)
def loadIncludes(self):
includeLocationNodes = self.evaluateXpath(
@ -164,15 +183,41 @@ class Schema(elements.Element):
includeLocationNode.content
for includeLocationNode in includeLocationNodes]
for includeLocation in self.includeLocations:
dataholders.walkToLocation(includeLocation)
self.walkToLocation(includeLocation)
class SchemaHolder(dataholders.XmlHolder):
defaultFileNameExtension = ".xsd"
def setupXml(self):
dataholders.XmlHolder.setupXml(self)
self.rootElement.loadIncludes()
class SchemaImplementation(stations.AbstractImplementation):
pass
class SchemasImplementation(stations.AbstractImplementation):
schemas = None
def __init__(self, specimen, internalWay = None, uriWay = None):
stations.AbstractImplementation.__init__(
self, None, specimen, internalWay = internalWay, uriWay = uriWay)
def getElementType(self, element):
if self.schemas is None:
return None
elementName = element.node.name
scannedSchemas = []
for schema in self.schemas:
elementType = schema.getGlobalElementType(
elementName, scannedSchemas = scannedSchemas)
if elementType is not None:
return elementType
scannedSchemas.append(self)
return None
def getPrototype(self):
return self
prototype = property(getPrototype)
class Type(elements.Element):
@ -270,6 +315,31 @@ class Type(elements.Element):
def getSchema(self):
return self.dataHolder
def getTypeAtXpath(self, xpath):
"""Xpath must be a simple xpath expression."""
if not xpath:
return self
splitedXpath = xpath.split("/", 1)
name = splitedXpath[0]
assert name
if "[" in name:
name = name[:name.index("[")]
if name[0] == "@":
# Attribute
subType = self.getAttributeType(name[1:])
else:
# Child
subType = self.getChildType(name)
if subType is None:
raise Exception("""Unknown type for %s in "%s".""" % (
name, self.name))
if len(splitedXpath) > 1:
xpath = splitedXpath[1]
if xpath:
return subType.getTypeAtXpath(xpath)
return subType
name = property(getName)
schema = property(getSchema)
@ -372,11 +442,12 @@ class ObjectType(Type):
sourceNodes = environs.getVar("currentActionHandler").evaluateXpath(
"@src", valueNode)
if sourceNodes:
location = sourceNodes[0].content
dataHolder = dataholders.walkToLocation(location)
if dataHolder is not None:
return [html.a(dataHolder.simpleLabel,
href = locations.getUri(location))]
sourceLocation = sourceNodes[0].content
source = self.walkToLocation(sourceLocation)
if source is not None:
sourceDataHolder = source.dataHolder
return [html.a(sourceDataHolder.simpleLabel,
href = self.constructUri(location))]
return [valueNode.content]
def convertValueNodeToPlainText(self, valueNode):
@ -398,7 +469,7 @@ class SpipType(Type):
return result
def newType(node, dataHolder = None, parent = None):
def newType(node, parent = None):
## namespaceUri = node.ns().content
## namespaceNames = {
## namespaces.yep.uri: None,
@ -408,7 +479,7 @@ def newType(node, dataHolder = None, parent = None):
## raise Exception(
## "Unknown XML namespace URI = \"%s\"" % namespaceUri)
## namespaceName = namespaceNames[namespaceUri]
type = Type(node, dataHolder = dataHolder, parent = parent)
type = Type(node, parent = parent)
## if namespaceName is None:
## name = type.name
## else:

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -36,13 +35,14 @@ import namespaces
def _getActionUrl(ctx, action):
try:
dataHolder = environs.getVar("currentActionHandler").dataHolder
dataHolder = environs.getVar("currentStation").dataHolder
return dataHolder.getActionUri(action)
except:
logs.exception(
"""An exception occured in XPath function "getActionUrl":""")
raise
def _if(ctx, condition, trueValue, falseValue):
try:
if condition:
@ -53,6 +53,7 @@ def _if(ctx, condition, trueValue, falseValue):
logs.exception("""An exception occured in XPath function "if":""")
raise
def registerFunctions(xpathContext):
# We don't use None as namespace URI, because it seems the XForms "if"
# function only accepts strings for trueValue and falseValue.

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -53,7 +52,7 @@ class Multipart(WidgetElement):
if childNode.type in ("comment", "text"):
childNode = childNode.next
continue
element = elements.newElement(childNode, parent = self)
element = self.newElement(childNode)
message.attach(element.generateEmailMessageBody())
childNode = childNode.next
return message
@ -84,13 +83,13 @@ class Address(WidgetElement):
nodes = self.evaluateXpath("mail:email")
if not nodes:
return None
return elements.newElement(nodes[0], parent = self)
return self.newElement(nodes[0])
def getName(self):
nodes = self.evaluateXpath("mail:name")
if not nodes:
return None
return elements.newElement(nodes[0], parent = self)
return self.newElement(nodes[0])
email = property(getEmail)
name = property(getName)
@ -103,43 +102,40 @@ class Alternative(Multipart):
class Message(WidgetElement):
def getBccAddresses(self):
addressNodes = self.evaluateXpath("mail:bcc")
return [elements.newElement(addressNode, parent = self)
for addressNode in addressNodes]
return [self.newElement(addressNode) for addressNode in addressNodes]
def getBody(self):
nodes = self.evaluateXpath(
"html:html | mail:alternative | mail:mixed | mail:plain")
if not nodes:
return None
return elements.newElement(nodes[0], parent = self)
return self.newElement(nodes[0])
def getCcAddresses(self):
addressNodes = self.evaluateXpath("mail:cc")
return [elements.newElement(addressNode, parent = self)
for addressNode in addressNodes]
return [self.newElement(addressNode) for addressNode in addressNodes]
def getFromAddress(self):
nodes = self.evaluateXpath("mail:from")
if not nodes:
return None
return elements.newElement(nodes[0], parent = self)
return self.newElement(nodes[0])
def getHtmlBody(self):
nodes = self.evaluateXpath("mail:htmlbody")
if not nodes:
return None
return elements.newElement(nodes[0], parent = self)
return self.newElement(nodes[0])
def getSubject(self):
nodes = self.evaluateXpath("mail:subject")
if not nodes:
return None
return elements.newElement(nodes[0], parent = self)
return self.newElement(nodes[0])
def getToAddresses(self):
addressNodes = self.evaluateXpath("mail:to")
return [elements.newElement(addressNode, parent = self)
for addressNode in addressNodes]
return [self.newElement(addressNode) for addressNode in addressNodes]
def makeMessage(self):
body = self.body

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -26,11 +25,11 @@
"""Groups Module"""
import dataholders
import elements
import locations
import modules
import namespaces
import stations
class DataHolderPointer(elements.Element):
@ -38,7 +37,7 @@ class DataHolderPointer(elements.Element):
nodes = self.evaluateXpath("@src")
if not nodes:
return None
return locations.getAbsoluteUri(nodes[0].content)
return self.constructAbsoluteUri(nodes[0].content)
class Everybody(elements.Element):
@ -89,7 +88,7 @@ class Group(elements.Element):
"@src", contextNode = memberNode)
if not memberSourceNodes:
continue
memberAbsoluteUri = locations.getAbsoluteUri(
memberAbsoluteUri = self.constructAbsoluteUri(
memberSourceNodes[0].content)
if memberAbsoluteUri == identityAbsoluteUri:
return True
@ -98,7 +97,8 @@ class Group(elements.Element):
if not indirect:
return False
if groupAbsoluteUris:
groupsHolder = dataholders.walkToLocation("/groups")
groups = self.walkToLocation("/groups")
groupsHolder = groups.dataHolder
for groupAbsoluteUri in groupAbsoluteUris:
group = groupsHolder.getItem(
locations.extractUriLocalId(groupAbsoluteUri))
@ -124,7 +124,7 @@ class Group(elements.Element):
nodes = self.evaluateXpath("yep:members")
if not nodes:
return None
return Members(nodes[0], dataHolder = self)
return Members(nodes[0], parent = self)
def getName(self):
nodes = self.evaluateXpath("yep:name")

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -28,11 +27,11 @@
import libxml2
import dataholders
import directories
import elements
import modules
import namespaces
import stations
class Identification(elements.Element):
@ -116,7 +115,7 @@ class Identity(elements.Element):
nodes = self.evaluateXpath("yep:identifications")
if not nodes:
return None
return Identifications(nodes[0], dataHolder = self)
return Identifications(nodes[0], parent = self)
def getLanguage(self):
nodes = self.evaluateXpath("yep:language")
@ -125,7 +124,7 @@ class Identity(elements.Element):
personLocation = self.personLocation
if not personLocation:
return None
person = dataholders.walkToLocation(personLocation)
person = self.walkToLocation(personLocation)
return person.language
def getPersonLocation(self):
@ -144,7 +143,7 @@ class Identity(elements.Element):
personLocation = self.personLocation
if not personLocation:
return _("Anonymous Identity #%s") % self.dataHolder.localId
person = dataholders.walkToLocation(personLocation)
person = self.walkToLocation(personLocation)
return person.simpleLabel
def getVoteToken(self, ballotBoxLocalId):

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -43,7 +42,6 @@ except ImportError:
sso = None
import libxml2
import dataholders
import directories
import elements
import environs
@ -55,10 +53,11 @@ import logs
import modules
import namespaces
import sessions
import stations
deleteSessionOnLogout = True
#symmetricKey = 'Glasnost-XML rules!' # FIXME
#symmetricKey = "Expression rules!" # FIXME
class EntityDescriptor(elements.Element):
@ -146,7 +145,7 @@ class LibertyAlliance(directories.Directory):
if not self.identityProviderLocation:
return self.loginLocalToUrl(nextUrl)
try:
identityProvider = dataholders.walkToLocation(
identityProvider = self.walkToLocation(
self.dataHolder.getSubPathInternUri(
self.identityProviderLocation))
except faults.PathNotFound:
@ -194,14 +193,16 @@ class LibertyAlliance(directories.Directory):
if session is None or user is None:
return
del user.sessionLocation
user.dataHolder.save()
userHolder = user.dataHolder
userHolder.save()
if removeFromEnviron:
baseEnviron = environs.get(_level = 'handleHttpCommand')
baseEnviron.setVar('user', None)
baseEnviron = environs.get(_level = "handleHttpCommand")
baseEnviron.setVar("user", None)
if deleteSessionOnLogout:
session.dataHolder.deleteStorage()
sessionHolder = session.dataHolder
sessionHolder.destroy()
if removeFromEnviron:
baseEnviron.setVar('session', None)
baseEnviron.setVar("session", None)
else:
# Don't delete the session, just remove user from it.
if session.userLocation is not None:
@ -213,8 +214,8 @@ class LibertyAlliance(directories.Directory):
def logoutToUrl(self, nextUrl = None):
if not nextUrl:
nextUrl = '/'
session = environs.getVar('session')
nextUrl = "/"
session = environs.getVar("session")
user = environs.getVar("user")
self.logoutSession(session, user, removeFromEnviron = True)
if deleteSessionOnLogout:
@ -230,48 +231,48 @@ class LibertyAlliance(directories.Directory):
httpPort = environs.getVar('httpPort')
if httpPort != 80:
uriAuthority = '%s:%d' % (uriAuthority, httpPort)
nextUrlAbsolutePath = locations.getUriAbsolutePath(nextUrl)
nextUrlAbsolutePath = self.constructUriAbsolutePath(nextUrl)
nextUrl = 'http://%s%s' % (uriAuthority, nextUrlAbsolutePath)
# The session is not always deleted on logout...
if not environs.getVar('canUseCookie'):
session = environs.getVar('session')
if not environs.getVar("canUseCookie"):
session = environs.getVar("session")
if session is not None:
nextUrl = appendParameterToUrl(
nextUrl, 'sessionToken', session.dataHolder.localId)
nextUrl = locations.appendParameterToUrl(
nextUrl, "sessionToken", session.dataHolder.localId)
else:
nextUrl = locations.getUri(nextUrl)
nextUrl = self.constructUri(nextUrl)
return environs.getVar('httpRequestHandler').outputRedirect(nextUrl)
def modeAccessIsAuthorized(self, modeName):
if modeName == 'logout':
return environs.getVar('user') is not None
if modeName == "logout":
return environs.getVar("user") is not None
elif modeName in self.handledActionNames:
return environs.getVar('user') is None
return environs.getVar("user") is None
return directories.Directory.modeAccessIsAuthorized(self, modeName)
def processAuthenticationResponse(self):
"""Service provider method called after login on identity provider"""
fieldStorage = environs.getVar('fieldStorage')
fieldStorage = environs.getVar("fieldStorage")
keywords = {}
for key in fieldStorage.keys():
keywords[key] = fieldStorage.getvalue(key)
# Create the service provider side session.
dataHolder = self.dataHolder
nextUrl = dataHolder.getActionUri('processAuthenticationResponse')
nextUrl = dataHolder.getActionUri("processAuthenticationResponse")
for key, value in keywords.items():
nextUrl = locations.appendParameterToUrl(nextUrl, key, value)
if sessions.createSessionIfNeeded(nextUrl):
return
identityProvider = dataholders.walkToLocation(
identityProvider = self.walkToLocation(
dataHolder.getSubPathInternUri(self.identityProviderLocation))
identityProviderHostName = identityProvider.providerId
if keywords.has_key('LARES'):
if keywords.has_key("LARES"):
# POST
authenticationResponseEmbedded = keywords['LARES']
authenticationResponseEmbedded = keywords["LARES"]
# Remove base64 url encoding.
authenticationResponseEmbeddedDecoded \
@ -279,11 +280,11 @@ class LibertyAlliance(directories.Directory):
authenticationResponseEmbedded)
authenticationResponseKeywords = {}
for segment in authenticationResponseEmbeddedDecoded.split('&'):
keyAndValue = segment.split('=', 1)
for segment in authenticationResponseEmbeddedDecoded.split("&"):
keyAndValue = segment.split("=", 1)
if len(keyAndValue) != 2:
logs.info(
'Wrong segment "segment" in response.' % segment)
"""Wrong segment "segment" in response.""" % segment)
continue
key, value = keyAndValue
authenticationResponseKeywords[key] = value
@ -319,13 +320,13 @@ class LibertyAlliance(directories.Directory):
message = _('Liberty Alliance authentication response'
' failed (reason = %s).') % statusCode
return environs.getVar('httpRequestHandler').outputAlert(
message, title = N_('Failure'), url = locations.getUri('/'))
message, title = N_('Failure'), url = self.constructUri('/'))
assertion = response.getAssertion()
idpNameIdentifier = assertion.getIDPProvidedNameIdentifier()
nameIdentifier = assertion.getNameIdentifier()
identitiesDirectory = dataholders.walkToLocation('/identities')
identitiesDirectory = self.walkToLocation('/identities')
if nameIdentifier and nameIdentifier != idpNameIdentifier:
user = identitiesDirectory.checkLocalNameIdentifier(
identityProviderHostName, nameIdentifier)
@ -336,29 +337,30 @@ class LibertyAlliance(directories.Directory):
identityHolderConstructor = modules.getHolderConstructor(
namespaces.yep.uri, 'identity')
userHolder = identityConstructor(identitiesDirectory)
user = userHolder.actionHandler
user = userHolder.walk([])
## user.language = environs.getVar('readLanguages')[0]
identifications = identities.Identifications(
libxml2.newNode('identifications'), dataHolder = self)
libxml2.newNode('identifications'), parent = self)
user.identifications = identifications
identification = identities.Identification(
libxml2.newNode('identification'))
identifications.append(identification)
if nameIdentifier and nameIdentifier != idpNameIdentifier:
identification.localNameIdentifier = nameIdentifier
identification.providerId = identityProviderHostName
identification.peerNameIdentifier = idpNameIdentifier
# userHolder.save() is done below.
# The following line is done below.
# user.dataHolder.save()
session = environs.getVar('session')
session = environs.getVar("session")
session.peerHostName = identityProviderHostName
session.authenticationMethod = assertion.getAuthenticationMethod()
session.userLocation = user.dataHolder.uriInternPath
user.sessionLocation = session.dataHolder.uriInternPath
session.userLocation = user.uriInternPath
user.sessionLocation = session.uriInternPath
user.dataHolder.save()
baseEnviron = environs.get(_level = 'handleHttpCommand')
baseEnviron.setVar('user', user)
baseEnviron = environs.get(_level = "handleHttpCommand")
baseEnviron.setVar("user", user)
## # Change the Name Identifier :
## # change in local data :
@ -383,7 +385,7 @@ class LibertyAlliance(directories.Directory):
nextUrl = None
if not nextUrl:
nextUrl = '/'
nextUrl = locations.getUri(nextUrl)
nextUrl = self.constructUri(nextUrl)
return environs.getVar('httpRequestHandler').outputRedirect(nextUrl)
def processIdentificationCreationRequest(self):
@ -401,8 +403,9 @@ class LibertyAlliance(directories.Directory):
for key in fieldStorage.keys():
keywords[key] = fieldStorage.getvalue(key)
identityProvider = dataholders.walkToLocation(
self.dataHolder.getSubPathInternUri(self.identityProviderLocation))
dataHolder = self.dataHolder
identityProvider = self.walkToLocation(
dataHolder.getSubPathInternUri(self.identityProviderLocation))
identityProviderHostName = identityProvider.providerId
if keywords.has_key('LARES'):
@ -456,14 +459,14 @@ class LibertyAlliance(directories.Directory):
'Identification creation request failed (reason = %s).') \
% statusCode
return environs.getVar('httpRequestHandler').outputAlert(
message, title = N_('Failure'), url = locations.getUri('/'))
message, title = N_('Failure'), url = self.constructUri('/'))
assertion = request.getAssertion()
idpNameIdentifier = assertion.getIDPProvidedNameIdentifier()
nameIdentifier = assertion.getNameIdentifier()
if relayState:
personsDirectory = dataholders.walkToLocation('/persons')
personsDirectory =self.walkToLocation('/persons')
personHolderConstructor = modules.getHolderConstructor(
namespaces.yep.uri, 'person')
personHolder = personHolderConstructor(personsDirectory)
@ -474,18 +477,18 @@ class LibertyAlliance(directories.Directory):
if len(personFields) > 1 and personFields[1]:
person.authorizations = personFields[1]
personHolder.save()
personLocation = personHolder.uriInternPath
personLocation = person.uriInternPath
else:
personLocation = None
identitiesDirectory = dataholders.walkToLocation('/identities')
identitiesDirectory = self.walkToLocation("/identities")
identityHolderConstructor = modules.getHolderConstructor(
namespaces.yep.uri, 'identity')
userHolder = identityHolderConstructor(identitiesDirectory)
user = userHolder.actionHandler
## user.language = environs.getVar('readLanguages')[0]
identifications = identities.Identifications(
libxml2.newNode('identifications'), dataHolder = self)
libxml2.newNode('identifications'), parent = self)
user.identifications = identifications
identification = identities.Identification(
libxml2.newNode('identification'))
@ -496,15 +499,16 @@ class LibertyAlliance(directories.Directory):
identification.peerNameIdentifier = idpNameIdentifier
if personLocation:
user.personLocation = personLocation
userHolder.save()
user.dataHolder.save()
message = _('Identification creation request succeeded.')
return environs.getVar('httpRequestHandler').outputAlert(
message, title = N_('Success'), url = locations.getUri('/'))
message, title = N_('Success'), url = self.constructUri('/'))
def sendSoapRequest(self, request):
identityProvider = dataholders.walkToLocation(
self.dataHolder.getSubPathInternUri(self.identityProviderLocation))
dataHolder = self.dataHolder
identityProvider = self.walkToLocation(
dataHolder.getSubPathInternUri(self.identityProviderLocation))
identityProviderHostName = identityProvider.providerId
idpParsedSoapEndpoint = urlparse.urlparse(
identityProvider.soapEndpoint)
@ -517,7 +521,7 @@ class LibertyAlliance(directories.Directory):
if idpAddressingScheme == 'https':
# Use HTTPS protocol.
# FIXME: Use PEM stored in glasnost attributes.
# FIXME: Use PEM stored in Expression attributes.
#shortHostName = environs.getVar('uriAuthority').split('.')[0]
shortHostName = 'mairie'
connection = http.HttpsConnection(
@ -550,16 +554,16 @@ Error:
' provider.')
return environs.getVar('httpRequestHandler').outputAlert(
message, title = N_('Failure'),
url = locations.getUri('/'))
url = self.constructUri('/'))
responseDom = libxml2.parseMemory(responseXml, len(responseXml))
response = schemaDom.importFromNode(responseDom, 1)
return response
def walkActions1(self, httpNames):
name = httpNames[0]
if name in self.handledActionNames and hasattr(self, name):
return self.do(name, httpNames[1:], getattr(self, name))
return directories.Directory.walkActions1(self, httpNames)
#~ def walkActions1(self, httpNames):
#~ name = httpNames[0]
#~ if name in self.handledActionNames and hasattr(self, name):
#~ return self.do(name, httpNames[1:], getattr(self, name))
#~ return directories.Directory.walkActions1(self, httpNames)
modules.registerElementClass(

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -28,7 +27,6 @@
import libxml2
import dataholders
import elements
import emails
import environs
@ -38,11 +36,16 @@ import logs
import modules
import namespaces
import sessions
import stations
import strings
class PasswordAccount(elements.Element):
submitActionNames = elements.Element.submitActionNames + ("login", "logout")
methodActionNames = elements.Element.methodActionNames.copy()
methodActionNames.update({
"login": "doHttpLogin",
"logout": "doHttpLogout",
})
def deleteAfterLoginUrl(self):
nodes = self.evaluateXpath("yep:afterLoginUrl")
@ -51,6 +54,24 @@ class PasswordAccount(elements.Element):
node.unlinkNode()
node.freeNode()
def doHttpLogin(self):
fieldStorage = environs.getVar("fieldStorage")
if fieldStorage.has_key("nextUrl"):
nextUrl = fieldStorage.getvalue("nextUrl")
if not nextUrl:
nextUrl = None
else:
nextUrl = None
return self.login(nextUrl)
def doHttpLogout(self):
fieldStorage = environs.getVar("fieldStorage")
if fieldStorage.has_key("nextUrl"):
nextUrl = fieldStorage.getvalue("nextUrl")
else:
nextUrl = None
return self.logout(nextUrl)
def getAfterLoginUrl(self):
nodes = self.evaluateXpath("yep:afterLoginUrl")
if nodes:
@ -72,17 +93,7 @@ class PasswordAccount(elements.Element):
else:
return None
def login(self):
fieldStorage = environs.getVar("fieldStorage")
if fieldStorage.has_key("nextUrl"):
nextUrl = fieldStorage.getvalue("nextUrl")
if not nextUrl:
nextUrl = None
else:
nextUrl = None
return self.loginToUrl(nextUrl)
def loginToUrl(self, nextUrl = None):
def login(self, nextUrl = None):
# Create the session.
currentUrl = self.dataHolder.absoluteUri # "login is the default action.
fieldStorage = environs.getVar("fieldStorage")
@ -100,14 +111,6 @@ class PasswordAccount(elements.Element):
environs.setVar("pageName", "edit")
self.output()
def logout(self):
fieldStorage = environs.getVar("fieldStorage")
if fieldStorage.has_key("nextUrl"):
nextUrl = fieldStorage.getvalue("nextUrl")
else:
nextUrl = None
return self.logoutToUrl(nextUrl)
def logoutSession(self, session, user, removeFromEnviron = False):
if session is None or user is None:
return
@ -116,16 +119,17 @@ class PasswordAccount(elements.Element):
if removeFromEnviron:
baseEnviron = environs.get(_level = "handleHttpCommand")
baseEnviron.setVar("user", None)
session.dataHolder.deleteStorage()
session.dataHolder.destroy()
if removeFromEnviron:
baseEnviron.setVar("session", None)
def logoutToUrl(self, nextUrl = None):
def logout(self, nextUrl = None):
if not nextUrl:
nextUrl = "/"
session = environs.getVar("session")
user = environs.getVar("user")
self.logoutSession(session, user, removeFromEnviron = True)
self.logoutSession(
session, user, removeFromEnviron = True)
nextUrl = locations.cleanUpUrl(nextUrl, "sessionToken")
if environs.getVar("uriScheme") == "https" \
and environs.getVar("httpPort") is not None:
@ -138,10 +142,10 @@ class PasswordAccount(elements.Element):
httpPort = environs.getVar("httpPort")
if httpPort != 80:
uriAuthority = "%s:%d" % (uriAuthority, httpPort)
nextUrlAbsolutePath = locations.getUriAbsolutePath(nextUrl)
nextUrlAbsolutePath = self.constructUriAbsolutePath(nextUrl)
nextUrl = "http://%s%s" % (uriAuthority, nextUrlAbsolutePath)
else:
nextUrl = locations.getUri(nextUrl)
nextUrl = self.constructUri(nextUrl)
return environs.getVar("httpRequestHandler").outputRedirect(nextUrl)
def modeAccessIsAuthorized(self, modeName):
@ -159,13 +163,13 @@ class PasswordAccount(elements.Element):
if environs.getVar("debug"):
raise Exception(
"""Description "%s" missing""" % self.descriptionLocation)
raise faults.PathNotFound(dataHolder.uriInternPath)
raise faults.PathNotFound(self.uriInternPath)
description.submit()
alerts = {}
if not self.email:
alerts["yep_email"] = "Adresse de courriel manquante"
try:
inscription = dataholders.walkToLocation(
inscription = self.walkToLocation(
"/inscriptions/%s" % strings.simplify(self.email))
except faults.PathNotFound:
alerts["yep_email"] = "Adresse de courriel inconnue"
@ -211,10 +215,10 @@ Léquipe Villes Internet
except: # TODO: tighter check
return environs.getVar("httpRequestHandler").outputAlert(
"L'envoi de votre identifiant par courriel a échoué.",
title = "Échec", url = locations.getUri("/"))
title = "Échec", url = self.constructUri("/"))
return environs.getVar("httpRequestHandler").outputAlert(
"Votre identifiant vient de vous être envoyé envoyé par"
" courriel.", title = "Succès", url = locations.getUri("/"))
" courriel.", title = "Succès", url = self.constructUri("/"))
if not self.password:
alerts["yep_password"] = "Identifiant manquant"
elif self.password != inscription.password:
@ -222,8 +226,8 @@ Léquipe Villes Internet
else:
session = environs.getVar("session")
session.authenticationMethod = "password"
session.userLocation = inscription.dataHolder.uriInternPath
inscription.sessionLocation = session.dataHolder.uriInternPath
session.userLocation = inscription.uriInternPath
inscription.sessionLocation = session.uriInternPath
inscription.dataHolder.save()
baseEnviron = environs.get(_level = "handleHttpCommand")
baseEnviron.setVar("user", inscription)
@ -233,7 +237,7 @@ Léquipe Villes Internet
nextUrl = self.afterLoginUrl
if not nextUrl:
nextUrl = "/questionnaire"
nextUrl = locations.getUri(nextUrl)
nextUrl = self.constructUri(nextUrl)
return environs.getVar('httpRequestHandler').outputRedirect(
nextUrl)
# Error in the login form.
@ -247,12 +251,12 @@ Léquipe Villes Internet
finally:
environs.pull(_level = "submitToUrl")
def walkActions1(self, httpNames):
name = httpNames[0]
if name in ("doHttpRequest", "exists", "isAuthorized") \
and environs.getVar("pageName") is None:
return self.do("login", httpNames, self.login)
return elements.Element.walkActions1(self, httpNames)
#~ def walkActions1(self, httpNames):
#~ name = httpNames[0]
#~ if name in ("doHttpRequest", "exists", "isAuthorized") \
#~ and environs.getVar("pageName") is None:
#~ return self.do("login", httpNames, self.login)
#~ return elements.Element.walkActions1(self, httpNames)
afterLoginUrl = property(
getAfterLoginUrl, setAfterLoginUrl, deleteAfterLoginUrl)

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or

View File

@ -1,11 +1,10 @@
# -*- coding: UTF-8 -*-
# Glasnost-XML
# By: Frederic Peters <fpeters@entrouvert.be>
# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
# Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2003 Entr'ouvert & Emmanuel Raviart
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# This program is free software; you can redistribute it and/or
@ -31,6 +30,7 @@ layout a XML data holder.
import libxml2
import libxslt
import dataholders
import elements
@ -40,6 +40,8 @@ import logs
import modules
import namespaces
import parsers
import stations
import steps
import xforms
@ -47,29 +49,28 @@ class ActionButton(xforms.Control):
fieldValue = None
htmlControlClass = "yep-action-button"
def generateHtmlControlCoreForm(self, layout):
def generateHtmlImplementationControlCoreForm(self, implementation, layout):
layout.append(html.input(
class_ = 'button', name = self.action, type = 'submit',
value = self.label.node.content))
return True
def generateHtmlControlCoreStatic(self, layout):
def generateHtmlImplementationControlCoreStatic(self, implementation, layout):
label = self.label
if label is None:
return False
currentActionHandler = environs.getVar('currentActionHandler')
a = html.a(
class_ = 'button',
href = currentActionHandler.dataHolder.getActionUri(self.action))
if not label.generateHtmlMessageChildren(a):
href = implementation.dataHolder.getActionUri(self.action))
if not label.generateHtmlImplementationMessageChildren(implementation, a):
return False
layout.append(a)
return True
def generateHtmlControlCoreHidden(self, layout):
def generateHtmlImplementationControlCoreHidden(self, implementation, layout):
return False
def generateHtmlControlLabel(self, layout):
def generateHtmlImplementationControlLabel(self, implementation, layout):
return False
def getAction(self):
@ -81,35 +82,31 @@ class ActionButton(xforms.Control):
if not refNodes:
return actionNodes[0].content
ref = refNodes[0].content
#actionNodes = self.getValueNodes(subXpath = ref)
#actionNodes = self.getInstanceDataNodes(subXpath = ref)
valueNode = self.valueNode
if valueNode is None:
return None
currentActionHandler = environs.getVar('currentActionHandler')
actionNodes = currentActionHandler.evaluateXpath(
actionNodes = implementation.evaluateXpath(
ref, contextNode = valueNode)
if not actionNodes:
return None
return actionNodes[0].content
def isRelevant(self):
action = self.action
currentActionHandler = environs.getVar('currentActionHandler')
if not currentActionHandler.walk([action, 'exists']) \
or not currentActionHandler.walk([action, 'isAuthorized']):
return False
return xforms.Control.isRelevant(self)
#~ def isRelevant(self):
#~ action = self.action
#~ if not implementation.walk([action, 'exists']) \
#~ or not implementation.walk([action, 'isAuthorized']):
#~ return False
#~ return xforms.Control.isRelevant(self)
action = property(getAction)
relevant = property(isRelevant)
class Custom(xforms.Control):
htmlControlClass = "yep-custom"
def generateHtml(self, layout):
currentActionHandler = environs.getVar('currentActionHandler')
return getattr(currentActionHandler, self.functionName)(self, layout)
def generateHtmlImplementation(self, implementation, layout):
return getattr(implementation, self.functionName)(self, layout)
def getFunctionName(self):
nodes = self.evaluateXpath('@function')
@ -125,84 +122,15 @@ class Custom(xforms.Control):
class Description(elements.Element):
externalModelLocations = None
_pages = None
def fillInstancePageBodyLayout(self, layout, inForm = False):
"""Layout page body."""
pageName = environs.getVar('pageName')
pageNode = self.getPageNode(pageName)
if pageNode is None:
return False
bodyNodes = self.evaluateXpath('yep:body', pageNode)
if bodyNodes:
childNode = bodyNodes[0].children
while childNode is not None:
if childNode.type == "comment":
childNode = childNode.next
continue
if childNode.type == "text":
layout.append(childNode.content)
childNode = childNode.next
continue
element = elements.newElement(childNode, dataHolder = self)
element.inForm = inForm
element.generateHtml(layout)
childNode = childNode.next
return True
else:
logs.info(
"""Missing body description for page named "%s".""" % pageName)
return False
def fillInstancePageLayout(self, layout):
pageName = environs.getVar('pageName')
pageNode = self.getPageNode(pageName)
if pageNode is None:
return False
inForm = self.instanceLayoutRequiresForm()
if inForm:
currentActionHandler = environs.getVar('currentActionHandler')
pageLayout = html.form(
action = currentActionHandler.dataHolder.getActionUri('submit'),
enctype = 'multipart/form-data', method = 'post')
layout.append(pageLayout)
if not environs.getVar('canUseCookie'):
session = environs.getVar('session')
if session is not None:
pageLayout.append(html.input(
name = 'sessionToken', type = 'hidden',
value = session.dataHolder.localId))
pageLayout.append(html.input(
name = 'pageName', type = 'hidden', value = pageName))
else:
pageLayout = layout
self.fillInstancePageBodyLayout(pageLayout, inForm = inForm)
# Layout page buttons bar.
buttonsBarLayout = html.div(class_ = 'buttons-bar')
actionButtonsBarLayout = html.span(class_ = 'action-buttons-bar')
buttonsBarLayout.append(actionButtonsBarLayout)
actionButtonsBarNodes = self.evaluateXpath(
'yep:actionButtonsBar', pageNode)
buttonsBarFilled = False
if actionButtonsBarNodes:
childNode = actionButtonsBarNodes[0].children
while childNode is not None:
if childNode.type == "text":
buttonsBarLayout.append(childNode.content)
childNode = childNode.next
continue
element = elements.newElement(childNode, dataHolder = self)
element.inForm = inForm
if element.generateHtml(buttonsBarLayout):
buttonsBarFilled = True
childNode = childNode.next
if buttonsBarFilled:
pageLayout.append(buttonsBarLayout)
return True
def buildXformsImplementation(self, implementation):
modelNodes = self.evaluateXpath("xforms:model")
for modelNode in modelNodes:
model = self.newElement(modelNode)
model.buildXformsImplementation(implementation)
implementation.xformsDefaultModel.defaultInstance \
= implementation.specimen
def getEmailMessageNames(self):
nodes = self.evaluateXpath("mail:message/@name")
@ -214,21 +142,24 @@ class Description(elements.Element):
logs.info(
"""Missing description for email message named "%s".""" % name)
return None
return elements.newElement(nodes[0], parent = instance)
return instance.newElement(nodes[0])
def getModel(self, id):
modelNodes = self.evaluateXpath('xforms:model[@id = "%s"]' % id)
if modelNodes:
modelNode = modelNodes[0]
return xforms.Model(modelNode, self)
if self.externalModelLocations:
for externalModelLocation in self.externalModelLocations:
externalDescriptions = dataholders.walkToLocation(
externalModelLocation)
model = externalDescriptions.getModel(id)
if model is not None:
return model
return None
def getPage(self, pageName):
if self._pages is None or pageName not in self._pages:
pageNode = self.getPageNode(pageName)
if pageNode is None:
return None
if self._pages is None:
self._pages = {}
pageInternalWay = steps.XmlPageStep(self.internalWay)
uriWay = self.uriWay
if uriWay is None:
pageUriWay = None
else:
pageUriWay = steps.UriStep(uriWay, pageName)
self._pages[pageName] = elements.newElement(
pageNode, pageInternalWay, None, pageUriWay)
return self._pages[pageName]
def getPageNames(self):
pageNameNodes = self.evaluateXpath('yep:page/@name')
@ -244,53 +175,210 @@ class Description(elements.Element):
return None
return pageNodes[0]
def instanceLayoutRequiresForm(self):
pageName = environs.getVar('pageName')
pageNode = self.getPageNode(pageName)
if pageNode is None:
pageNames = property(getPageNames)
class DescriptionImplementation(html.HtmlImplementationMixin,
stations.AbstractImplementation):
_pages = None
def __init__(self, prototype, specimen, internalWay = None, uriWay = None):
stations.AbstractImplementation.__init__(
self, prototype, specimen, internalWay = internalWay,
uriWay = uriWay)
self.prototype.buildXformsImplementation(self)
def getPage(self, pageName):
if self._pages is None or pageName not in self._pages:
pagePrototype = self.prototype.getPage(pageName)
if pagePrototype is None:
return None
if self._pages is None:
self._pages = {}
pageInternalWay = steps.XmlPageStep(self.internalWay)
uriWay = self.uriWay
if uriWay is None:
pageUriWay = None
else:
pageUriWay = steps.UriStep(uriWay, pageName)
self._pages[pageName] = PageImplementation(
pagePrototype, self.specimen, internalWay = pageInternalWay,
uriWay = pageUriWay)
return self._pages[pageName]
def walkToItem(self, httpNames):
if not httpNames:
return self, httpNames
pageNames = self.prototype.pageNames
pageName = None
itemName = httpNames[0]
if itemName in pageNames:
pageName = itemName
remainingHttpNames = httpNames[1:]
if pageName is None:
if "view" not in pageNames:
return self, httpNames
pageName = "view"
remainingHttpNames = httpNames
page = self.getPage(pageName)
return page, remainingHttpNames
class Page(xforms.Control):
def generateHtmlImplementation(self, implementation, layout):
oldFormCreationNeeded = implementation.formCreationNeeded
implementation.formCreationNeeded = self.instanceLayoutRequiresForm()
filled = xforms.Control.generateHtmlImplementation(self, implementation, layout)
implementation.formCreationNeeded = oldFormCreationNeeded
return filled
def generateHtmlImplementationControl(self, implementation, layout):
filled = self.generateHtmlImplementationPageControlBody(implementation, layout)
# Layout page buttons bar.
buttonsBarLayout = html.div(class_ = "buttons-bar")
actionButtonsBarLayout = html.span(class_ = "action-buttons-bar")
buttonsBarLayout.append(actionButtonsBarLayout)
actionButtonsBarNodes = self.evaluateXpath("yep:actionButtonsBar")
buttonsBarFilled = False
if actionButtonsBarNodes:
childNode = actionButtonsBarNodes[0].children
while childNode is not None:
if childNode.type == "text":
buttonsBarLayout.append(childNode.content)
childNode = childNode.next
continue
element = self.newElement(childNode)
# FIXME: create implementation.
if element.generateHtmlImplementation(implementation, buttonsBarLayout):
buttonsBarFilled = True
childNode = childNode.next
if buttonsBarFilled:
layout.append(buttonsBarLayout)
filled = True
return filled
def generateHtmlImplementationPageControlBody(self, implementation, layout):
"""Layout page without buttons bar."""
bodyNodes = self.evaluateXpath("yep:body")
if bodyNodes:
childNode = bodyNodes[0].children
while childNode is not None:
if childNode.type == "comment":
childNode = childNode.next
continue
if childNode.type == "text":
layout.append(childNode.content)
childNode = childNode.next
continue
element = self.newElement(childNode)
element.generateHtmlImplementation(implementation, layout)
childNode = childNode.next
return True
else:
return False
pageTypeNodes = self.evaluateXpath('@type', contextNode = pageNode)
def getBind(self, modelImplementation):
return None
def getChildInstanceDataXpath(self, modelImplementation):
return ""
def getModelId(self):
return None
def getName(self):
nameNodes = self.evaluateXpath("@name")
if not nameNodes:
return None
return nameNodes[0].content
def instanceLayoutRequiresForm(self):
pageTypeNodes = self.evaluateXpath("@type")
if pageTypeNodes:
pageType = pageTypeNodes[0].content
else:
pageType = None
return pageType == 'form'
def loadExternalModels(self):
externalModelLocationNodes = self.evaluateXpath('xforms:model/@src')
self.externalModelLocations = [
externalModelLocationNode.content
for externalModelLocationNode in externalModelLocationNodes]
for externalModelLocation in self.externalModelLocations:
dataholders.walkToLocation(externalModelLocation)
return pageType == "form"
def submit(self):
pageName = environs.getVar('pageName')
pageNode = self.getPageNode(pageName)
if pageNode is None:
logs.info(
"""Missing page named "%s".""" % pageName)
return
bodyNodes = self.evaluateXpath('yep:body', pageNode)
bodyNodes = self.evaluateXpath("yep:body")
if not bodyNodes:
logs.info(
"""Missing body description for page named "%s".""" % pageName)
controlNodes = self.evaluateXpath('*', bodyNodes[0])
"""Missing body description for page named "%s"."""
% self.localId)
controlNodes = self.evaluateXpath("*", bodyNodes[0])
for controlNode in controlNodes:
control = elements.newElement(controlNode, dataHolder = self)
control = self.newElement(controlNode)
control.submit()
modelId = property(getModelId)
name = property(getName)
class DescriptionHolder(dataholders.XmlHolder):
def setupXml(self):
dataholders.XmlHolder.setupXml(self)
self.rootElement.loadExternalModels()
class PageImplementation(stations.AbstractImplementation):
"""Page implementation defines every attributes of DescriptionImplementation
by delegating to the (previous) DescriptionImplementation."""
def generateHtml(self, layout):
return self.prototype.generateHtmlImplementation(self, layout)
def outputHttpSource(self):
self.specimen.outputHttpSource()
#
# DescriptionImplementation attributes
#
def deleteFormCreationNeeded(self):
del self.parent.formCreationNeeded
def deleteInForm(self):
del self.parent.inForm
def deleteXformsDefaultModel(self):
del self.parent.xformsDefaultModel
def deleteXformsModelsById(self):
del self.parent.xformsModelsById
def getFormCreationNeeded(self):
return self.parent.formCreationNeeded
def getInForm(self):
return self.parent.inForm
def getXformsDefaultModel(self):
return self.parent.xformsDefaultModel
def getXformsModelsById(self):
return self.parent.xformsModelsById
def setFormCreationNeeded(self, formCreationNeeded):
self.parent.formCreationNeeded = formCreationNeeded
def setInForm(self, inForm):
self.parent.inForm = inForm
def setXformsDefaultModel(self, xformsDefaultModel):
self.parent.xformsDefaultModel = xformsDefaultModel
def setXformsModelsById(self, xformsModelsById):
self.parent.xformsModelsById = xformsModelsById
formCreationNeeded = property(
getFormCreationNeeded, setFormCreationNeeded, deleteFormCreationNeeded)
inForm = property(getInForm, setInForm, deleteInForm)
xformsDefaultModel = property(
getXformsDefaultModel, setXformsDefaultModel, deleteXformsDefaultModel)
xformsModelsById = property(
getXformsModelsById, setXformsModelsById, deleteXformsModelsById)
class Spip(xforms.TextArea):
htmlControlClass = "yep-spip"
def generateHtmlControlCoreStatic(self, layout):
def generateHtmlImplementationControlCoreStatic(self, implementation, layout):
filled = False
content = self.node.content
if content:
@ -307,7 +395,5 @@ class Spip(xforms.TextArea):
modules.registerElementClass(namespaces.yep.uri, "actionButton", ActionButton)
modules.registerElementClass(namespaces.yep.uri, "custom", Custom)
modules.registerElementClass(namespaces.yep.uri, "description", Description)
modules.registerElementClass(namespaces.yep.uri, "page", Page)
modules.registerElementClass(namespaces.yep.uri, "spip", Spip)
modules.registerHolderClass(
namespaces.yep.uri, "description", DescriptionHolder)

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<passwordAccount schema="/schemas/PasswordAccount.xsd"
description="/descriptions/PasswordAccount.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<login>manou</login>
<password>manou</password>
<identity src="http://abracadabra/identities/1"/>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<ballotBox schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</ballotBox>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<election xmlns="http://abracadabra.entrouvert.org/0.0"
<election xmlns="http://www.entrouvert.org/namespaces/expression/0.0"
schema="/schemas/Election1.xsd"
description="/descriptions/Election1.xml">
<title>Aménagement du quartier</title>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<pageSequence xmlns="http://abracadabra.entrouvert.org/0.0"
<pageSequence xmlns="http://www.entrouvert.org/namespaces/expression/0.0"
schema="/schemas/PageSequence.xsd"
description="/descriptions/PageSequence.xml">
<title>Consultation sur l'amenagement du quartier</title>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<group xmlns="http://abracadabra.entrouvert.org/0.0"
<group xmlns="http://www.entrouvert.org/namespaces/expression/0.0"
schema="/schemas/Group.xsd"
description="/descriptions/Group.xml">
<name>Administrators</name>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<identities schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<users mode="new-yep-identity">
<group src="/groups/1"/>
</users>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<stylesheet src="/xslt/site.xsl"/>
<users mode="access">
<everybody/>
@ -9,6 +9,9 @@
<users mode="description">
<everybody/>
</users>
<users mode="doHttpRequest">
<everybody/>
</users>
<users mode="edit">
<everybody/>
</users>
@ -30,6 +33,9 @@
<users mode="source">
<everybody/>
</users>
<users mode="styled">
<everybody/>
</users>
<users mode="submit">
<everybody/>
</users>

View File

@ -2,7 +2,7 @@
<EntityDescriptor providerID="http://identification.vandoeuvre.grand-nancy.fr"
schema="/schemas/EntityDescriptor.xsd"
description="/descriptions/EntityDescriptor.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<IDPDescriptor>
<SingleLogoutServiceURL>https://identification.vandoeuvre.grand-nancy.fr/identities/singleLogoutServiceUrl</SingleLogoutServiceURL>
<RegisterNameIdentifierProtocolProfile>http://projectliberty.org/profiles/rni-sp-http</RegisterNameIdentifierProtocolProfile>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<libertyAlliance schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</libertyAlliance>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<person xmlns="http://abracadabra.entrouvert.org/0.0" schema="/schemas/Person.xsd" description="/descriptions/Person.xml">
<person xmlns="http://www.entrouvert.org/namespaces/expression/0.0" schema="/schemas/Person.xsd" description="/descriptions/Person.xml">
<lastName>Dupont</lastName>
<firstName>Jean</firstName>
<nickname>Jeannot</nickname><email>jean.dupont@wanadoo.fr</email><fullName>Jean Dupont</fullName><language>en</language><authorizations></authorizations></person>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<sessions schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</sessions>

View File

@ -1,8 +1,5 @@
# -*- coding: UTF-8 -*-
dataFile = file(self.absolutePath, "rb")
self.data = dataFile.read()
dataFile.close()
environs.getVar("httpRequestHandler").outputData(
self.data, contentLocation = self.uriAbsolutePath,
mimeType = self.mimeType, modificationTime = self.modificationTime)

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<votes schema="/schemas/Object.xsd"
description="/descriptions/Object.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</votes>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<bug xmlns="http://abracadabra.entrouvert.org/0.0" schema="/schemas/Bug.xsd" description="/descriptions/Bug.xml">
<bug xmlns="http://www.entrouvert.org/namespaces/expression/0.0" schema="/schemas/Bug.xsd" description="/descriptions/Bug.xml">
<category>test</category>
<assignedTo>fpeters@entrouvert.com</assignedTo>
<originator>fpeters@entrouvert.com</originator>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<users mode="edit">
<everybody/>
</users>

View File

@ -3,7 +3,7 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:yep="http://abracadabra.entrouvert.org/0.0">
xmlns:yep="http://www.entrouvert.org/namespaces/expression/0.0">
<xforms:model id="bugModel" schema="/schemas/Bug.xsd">
<xforms:submission action="file://tmp/abracadabra-put.xml" method="put" id="submit"/>
</xforms:model>

View File

@ -1,14 +1,13 @@
<?xml version="1.0"?>
<xsd:schema targetNameSpace="http://abracadabra.entrouvert.org/0.0"
xmlns="http://abracadabra.entrouvert.org/0.0"
<xsd:schema targetNameSpace="http://www.entrouvert.org/namespaces/expression/0.0"
xmlns="http://www.entrouvert.org/namespaces/expression/0.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:annotation>
<xsd:documentation xml:lang="en">
Bug Schema for Glasnost-XML.
By: Frederic Peters &lt;fpeters@entrouvert.be&gt;
Bug Schema for Expression.
By: Frederic Peters &lt;fpeters@entrouvert.com&gt;
Emmanuel Raviart &lt;eraviart@entrouvert.com&gt;
Copyright (C) 2003 Entr'ouvert &amp; Emmanuel Raviart
Copyright (C) 2004 Entr'ouvert, Frederic Peters &amp; Emmanuel Raviart
This program is free software; you can redistribute it and/or

View File

@ -48,7 +48,7 @@
</div>
<div id="footer">
<div id="lasso">
<a href="http://glasnost.entrouvert.org" title="LASSO">
<a href="http://www.entrouvert.org/lasso" title="LASSO">
<span>Lasso</span>
</a>
</div>

View File

@ -48,7 +48,7 @@
</div>
<div id="footer">
<div id="lasso">
<a href="http://glasnost.entrouvert.org" title="LASSO">
<a href="http://www.entrouvert.org/lasso" title="LASSO">
<span>Lasso</span>
</a>
</div>

View File

@ -48,7 +48,7 @@
</div>
<div id="footer">
<div id="lasso">
<a href="http://glasnost.entrouvert.org" title="LASSO">
<a href="http://www.entrouvert.org/lasso" title="LASSO">
<span>Lasso</span>
</a>
</div>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<article xmlns="http://abracadabra.entrouvert.org/0.0" schema="/schemas/Article.xsd" description="/descriptions/Article.xml">
<article xmlns="http://www.entrouvert.org/namespaces/expression/0.0" schema="/schemas/Article.xsd" description="/descriptions/Article.xml">
<title>Consultation de quartier</title>
<body>
Pour chacune des consultations suivantes, donnez votre avis (de "Pas du

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<article xmlns="http://abracadabra.entrouvert.org/0.0" schema="/schemas/Article.xsd" description="/descriptions/Article.xml">
<article xmlns="http://www.entrouvert.org/namespaces/expression/0.0" schema="/schemas/Article.xsd" description="/descriptions/Article.xml">
<title>Fin de la consultation</title>
<body>
Merci d'avoir rempli ce questionnaire.

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<ballotBox schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</ballotBox>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<election xmlns="http://abracadabra.entrouvert.org/0.0"
<election xmlns="http://www.entrouvert.org/namespaces/expression/0.0"
schema="/schemas/Election1.xsd"
description="/descriptions/Election1.xml">
<title>Aménagement du quartier</title>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<pageSequence xmlns="http://abracadabra.entrouvert.org/0.0"
<pageSequence xmlns="http://www.entrouvert.org/namespaces/expression/0.0"
schema="/schemas/PageSequence.xsd"
description="/descriptions/PageSequence.xml">
<title>Consultation sur l'aménagement du quartier</title>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<group xmlns="http://abracadabra.entrouvert.org/0.0"
<group xmlns="http://www.entrouvert.org/namespaces/expression/0.0"
schema="/schemas/Group.xsd"
description="/descriptions/Group.xml">
<name>Administrators</name>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<users mode="new-yep-identity">
<group src="/groups/1"/>
</users>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<users mode="edit">
<group src="/groups/1"/>
</users>

View File

@ -2,7 +2,7 @@
<EntityDescriptor providerID="http://identification.lesdemocratics.net"
schema="/schemas/EntityDescriptor.xsd"
description="/descriptions/EntityDescriptor.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<IDPDescriptor>
<SingleLogoutServiceURL>https://identification.lesdemocratics.net/identities/singleLogoutServiceUrl</SingleLogoutServiceURL>
<RegisterNameIdentifierProtocolProfile>http://projectliberty.org/profiles/rni-sp-http</RegisterNameIdentifierProtocolProfile>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<libertyAlliance schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</libertyAlliance>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<sessions schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</sessions>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<votes schema="/schemas/Object.xsd"
description="/descriptions/Object.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</votes>

View File

@ -2,7 +2,7 @@
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:yep="http://abracadabra.entrouvert.org/0.0"
xmlns:yep="http://www.entrouvert.org/namespaces/expression/0.0"
xsl:exclude-result-prefixes="yep">
<xsl:output method="xml" encoding="UTF-8" indent="yes"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"

View File

@ -48,7 +48,7 @@
</div>
<div id="footer">
<div id="lasso">
<a href="http://glasnost.entrouvert.org" title="LASSO">
<a href="http://www.entrouvert.org/lasso" title="LASSO">
<span>Lasso</span>
</a>
</div>

View File

@ -48,7 +48,7 @@
</div>
<div id="footer">
<div id="lasso">
<a href="http://glasnost.entrouvert.org" title="LASSO">
<a href="http://www.entrouvert.org/lasso" title="LASSO">
<span>Lasso</span>
</a>
</div>

View File

@ -48,7 +48,7 @@
</div>
<div id="footer">
<div id="lasso">
<a href="http://glasnost.entrouvert.org" title="LASSO">
<a href="http://www.entrouvert.org/lasso" title="LASSO">
<span>Lasso</span>
</a>
</div>
@ -56,3 +56,4 @@
</div>
</body>
</html>
www.entrouvert.org/lasso

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<ficheLiaison xmlns="http://abracadabra.entrouvert.org/0.0" schema="/schemas/FicheLiaison.xsd" description="/descriptions/FicheLiaison.xml">
<ficheLiaison xmlns="http://www.entrouvert.org/namespaces/expression/0.0" schema="/schemas/FicheLiaison.xsd" description="/descriptions/FicheLiaison.xml">
<themes></themes>
<quartier>paris3</quartier><dateEnvoiDemande></dateEnvoiDemande>
<referent src="/identities/704042371234"></referent>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<users mode="modification">
<group src="/groups/1"/>
</users>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<group xmlns="http://abracadabra.entrouvert.org/0.0"
<group xmlns="http://www.entrouvert.org/namespaces/expression/0.0"
schema="/schemas/Group.xsd"
description="/descriptions/Group.xml">
<name>Administrators</name>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<users mode="new-yep-identity">
<group src="/groups/1"/>
</users>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<users mode="edit">
<group src="/groups/1"/>
</users>

View File

@ -2,7 +2,7 @@
<EntityDescriptor providerID="http://identification.lesdemocratics.net"
schema="/schemas/EntityDescriptor.xsd"
description="/descriptions/EntityDescriptor.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<IDPDescriptor>
<SingleLogoutServiceURL>https://identification.lesdemocratics.net/identities/singleLogoutServiceUrl</SingleLogoutServiceURL>
<RegisterNameIdentifierProtocolProfile>http://projectliberty.org/profiles/rni-sp-http</RegisterNameIdentifierProtocolProfile>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<libertyAlliance schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</libertyAlliance>

View File

@ -47,7 +47,7 @@
</div>
<div id="footer">
<div id="lasso">
<a href="http://glasnost.entrouvert.org/lasso" title="LASSO">
<a href="http://www.entrouvert.org/lasso" title="LASSO">
<span>Lasso</span>
</a>
</div>

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<sessions schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
</sessions>

View File

@ -2,7 +2,7 @@
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:yep="http://abracadabra.entrouvert.org/0.0"
xmlns:yep="http://www.entrouvert.org/namespaces/expression/0.0"
xsl:exclude-result-prefixes="yep">
<xsl:output method="xml" encoding="UTF-8" indent="yes"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"

View File

@ -3,7 +3,7 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:yep="http://abracadabra.entrouvert.org/0.0">
xmlns:yep="http://www.entrouvert.org/namespaces/expression/0.0">
<xforms:model id="inscriptionModel" schema="/schemas/Inscription.xsd">
<!-- <xforms:bind nodeset="yep:password" relevant="false()"/> -->
<xforms:submission action="file://tmp/abracadabra-put.xml" method="put" id="submit"/>
@ -250,7 +250,7 @@
</yep:page>
<mail:message name="email"
xmlns:mail="http://glasnost.entrouvert.org/namespaces/email/0.0">
xmlns:mail="http://www.entrouvert.org/namespaces/email/0.0">
<mail:from>coordination@villes-internet.net</mail:from>
<mail:to><xforms:output model="inscriptionModel" ref="yep:courriel"/></mail:to>
<mail:subject>Identifiant pour accéder au Label Villes Internet 2004</mail:subject>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<yep:description schema="/schemas/Description.xsd"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:yep="http://abracadabra.entrouvert.org/0.0"
xmlns:yep="http://www.entrouvert.org/namespaces/expression/0.0"
xmlns:xforms="http://www.w3.org/2002/xforms">
<xforms:model id="passwordAccountModel"
schema="/schemas/PasswordAccount.xsd">

View File

@ -3,7 +3,7 @@
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:yep="http://abracadabra.entrouvert.org/0.0">
xmlns:yep="http://www.entrouvert.org/namespaces/expression/0.0">
<xforms:model id="questionnaireModel" schema="/schemas/Inscription.xsd">
<xforms:submission action="file://tmp/abracadabra-put.xml" method="put" id="submit"/>
</xforms:model>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<stylesheet src="/xslt/site.xsl"/>
<users mode="access">
<everybody/>

View File

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<directory schema="/schemas/Directory.xsd"
description="/descriptions/Directory.xml"
xmlns="http://abracadabra.entrouvert.org/0.0">
xmlns="http://www.entrouvert.org/namespaces/expression/0.0">
<users mode="edit">
</users>
<users mode="new">

Some files were not shown because too many files have changed in this diff Show More