- Réorg des web, edit, submit et tout. Plusieurs fois, et chaque fois un peu

plus loin.  A priori, sans trop tester (mais c'est la première fois que
  j'allais aussi loin dans les cards), ça fonctionne.  Il y a encore quelques
  questions mais on verra ça à Paris.  (il y a eu un conflit au niveau des
  Cards, je ne vérifie pas si ça fonctionen toujours, je n'ai pas vraiment le
  temps...) (normalement, oui)

- Ajout d'un LdapPeopleWeb pour aller chercher les personnes dans un annuaire
  LDAP.  Ça va de pair avec l'authentification LDAP et ça marche.

- Ajout d'un groupe "Logged Users" dont la possibilité a été découverte par
  hasard.  (le groupe "General Public" m'acceptait quand je n'étais pas loggé
  et me refusait quand j'étais loggé via LDAP, avec un userId != people)

- Ajout du support pour commentaires à un article, ça fonctionne mais c'est un
  peu caché pour le moment.

- ...
This commit is contained in:
fpeters 2003-10-26 09:18:03 +00:00
parent 99159e7dd7
commit af3c12c90b
82 changed files with 4326 additions and 6227 deletions

View File

@ -358,6 +358,7 @@ po: glasnost-web/ \
shared/proxy/ \
shared/server/ \
shared/web/ \
system/ \
talTranslations.py
cp po/glasnost-web/de.po po/glasnost-web/de.pox

View File

@ -80,9 +80,6 @@ UseHTTPS = false
The available options are:
BaseSectionLevel:
Define the base tag for article subtitles (default: 2 -> <h2>)
CacheFiles:
Define if Glasnost should cache page results in some circumstances (user
not logged, no active session...) (default: false)
@ -101,9 +98,12 @@ GettextDomains:
Allows to add more gettext domains to look in for translations.
Profiling:
Dumps profiling informations into /tmp/glasnost-web.prof
Dumps profiling informations into /tmp/
(default: false)
SectionLevel:
Define the base tag for article subtitles (default: 2 -> <h2>)
ShowFullListInSelectIdForServerRoles:
Define the server roles for which the whole list should appear in SelectId
<select> widgets (instead of the last visited objects).

View File

@ -105,6 +105,10 @@ class Application(applications.Application):
keywords = keywordsArguments.copy()
if objectId is not None:
keywords['id'] = objectId
if keywords.has_key('nextUri'):
context.setVar('nextUri', keywords['nextUri'])
del keywords['nextUri']
functionCode = function.func_code
expectedArguments = functionCode.co_varnames[:functionCode.co_argcount]
@ -242,6 +246,7 @@ class Application(applications.Application):
preferences = None,
readLanguages = None,
req = req,
sectionLevel = 1,
serverRole = None,
session = None,
sessionToken = None,
@ -560,7 +565,7 @@ class Application(applications.Application):
for language in languages]
try:
possibleLanguages = translationsProxy.getPossibleLanguages()
except faults.UnknownServerId:
except (faults.UnknownServerId, faults.UnknownDispatcherInId):
possibleLanguages = []
if not virtualHost.language in possibleLanguages:
possibleLanguages.append(virtualHost.language)
@ -662,9 +667,9 @@ class Application(applications.Application):
profiling = webTools.getConfig('Profiling', 'false') == 'true'
handlerContext.setVar('profiling', profiling)
baseSectionLevel = int(
webTools.getConfig('BaseSectionLevel', default = '2'))
handlerContext.setVar('baseSectionLevel', baseSectionLevel)
sectionLevel = int(
webTools.getConfig('sectionLevel', default = 1))
handlerContext.setVar('sectionLevel', sectionLevel)
cacheTime = int(webTools.getConfig('CacheTime', '15')) * 60
handlerContext.setVar('cacheTime', cacheTime)

View File

@ -418,3 +418,11 @@ ul.multi>li>div{
margin-bottom: 2em;
}
span.comment-no {
display: none;
}
ul.article-meta {
list-style: none;
}

View File

@ -51,7 +51,8 @@ import glasnost.common.xhtmlgenerator as X
from glasnost.web.tools import *
def index(nextUri = '', **keywords):
def index(**keywords):
nextUri = context.getVar('nextUri') or ''
if keywords is None:
keywords = {}
session = context.getVar('session')
@ -84,7 +85,8 @@ def index(nextUri = '', **keywords):
return redirect(uri)
def testCookie(nextUri = ''):
def testCookie():
nextUri = context.getVar('nextUri') or ''
session = context.getVar('session')
nextUri = cleanUpUri(nextUri, ['sessionToken'])
canUseCookie = context.getVar('canUseCookie', default = 0)
@ -93,3 +95,4 @@ def testCookie(nextUri = ''):
nextUri,
'sessionToken=' + context.getVar('sessionToken'))
return redirect(nextUri)

View File

@ -50,13 +50,16 @@ from glasnost.web.tools import *
def index(nextUri = '', access = '', again = '', error = '', **keywords):
authWeb = getWebForServerRole('authentication-login-password')
# TODO: getDefaultMethod
return authWeb.login(nextUri, access, again, error, **keywords)
def index(access = ''):
authAdmin = getWebForServerRole('authentication').getAdmin()
for authMethod in authAdmin.authenticationMethods or ['login-password']:
authWeb = getWebForServerRole('authentication-%s' % authMethod)
if authWeb:
break
return authWeb.login(access)
def logout(nextUri = ''):
def logout():
authWeb = getWebForServerRole('authentication')
return authWeb.logout(nextUri)
return authWeb.logout()

View File

@ -53,24 +53,25 @@ import glasnost.common.xhtmlgenerator as X
from glasnost.web.tools import *
def _switchLang(lang, nextUri):
def _switchLang(lang):
if not lang in languageKeys:
return writePageLayout(
X.p(_('The language you asked for is not available.')),
'Language not available')
nextUri = context.getVar('nextUri') or ''
if not nextUri:
nextUri = X.rootUrl()
uri = X.roleUrl('define').add('lang', lang).add('nextUri', nextUri)
return redirect(uri)
def english(nextUri = ''):
return _switchLang('en', nextUri)
def english():
return _switchLang('en')
def french(nextUri = ''):
return _switchLang('fr', nextUri)
def french():
return _switchLang('fr')
def spanish(nextUri = ''):
return _switchLang('es', nextUri)
def spanish():
return _switchLang('es')
index = _switchLang

View File

@ -9,7 +9,7 @@ then
fi
echo "Installing glasnost://system environment in root-system/"
mkdir system/data
test -d system/data || mkdir system/data
rm -f config && make config config-system install \
GLASNOST=glasnost-system PORT=8500 \
PREFIX=`pwd`/root-system/usr/local \

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -977,5 +977,6 @@ class ArticlesServer(ArticlesCommonMixin, ObjectsServer):
articlesServer = ArticlesServer()
if __name__ == "__main__":
if __name__ == '__main__':
articlesServer.launch(applicationName, applicationRole)

View File

@ -106,7 +106,9 @@ class AuthenticationLdapVirtualServer(AdministrableVirtualServer):
#'uid=%s, ou=People, o=entrouvert, c=be' %
except ldap.INVALID_CREDENTIALS:
raise faults.WrongPassword('****')
return 'glasnost://system/atoms/1'
return '%s/ldappeople/%s' % (
commonTools.extractDispatcherId(self.virtualServerId),
authenticationObject.login)
def deleteAccount(self, authenticationObject):
pass

View File

@ -123,7 +123,7 @@ class Card(ObjectServerMixin, CardCommon):
for slotName in ['properties', 'prototypeIds']:
slot = self.getSlot(slotName)
kind = slot.getKind()
if kind.isAutomaticalyModified:
if kind.isAutomaticallyModified:
kind.setAutomaticalValue(slot)
continue
if not kind.isImportable():

View File

@ -47,6 +47,7 @@ __version__ = '$Revision$'[11:-2]
import sys
import time
glasnostPythonDir = '/usr/local/lib/glasnost-devel' # changed on make install
sys.path.insert(0, glasnostPythonDir)
@ -74,62 +75,69 @@ register(AdminComments)
class Comment(ObjectServerMixin, CommentCommon):
pass
def checkAddIsPossible(self):
ObjectServerMixin.checkAddIsPossible(self)
virtualServerId = context.getVar('applicationId')
ultimateParentId = self.getServer().getParentId(self)
parent = getObject(ultimateParentId)
# if it booms out; adding was not possible, we get what we want
# TODO: parent object should tell if it accepts comments
def modify(self, changes, givenSlotNames = None):
return ObjectServerMixin.modify(self, changes,
['language', 'title', 'body'])
def setAutomaticalSlots(self, parentSlot = None):
ObjectServerMixin.setAutomaticalSlots(self, parentSlot = parentSlot)
self.authorId = getProxyForServerRole('authentication').getUserId()
self.creationTime = time.time()
register(Comment)
class CommentsServer(CommentsCommonMixin, ObjectsServer):
useAdminWritersSet = 1
def canAddObject(self):
# FIXME: should check if parent forum allows anonymous posts
return 1
def getComments(self, replyToId):
def canGetObject(self, objectId):
result = ObjectsServer.canGetObject(self, objectId)
if result == 0:
return 0
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
objects = virtualServer.objects.values()
ids = [o.id for o in objects if o.replyToId == replyToId]
# Sort the comments by chronological order.
ids.sort(lambda id1, id2:
cmp(int(commonTools.extractLocalId(id1)),
int(commonTools.extractLocalId(id2))))
return [self.getObjectXmlRpc(commentId) for commentId in ids]
object = virtualServer.loadObjectCore(objectId)
parentId = self.getParentId(object)
roleProxy = getProxyForServerRole(
commonTools.extractRole(parentId))
return roleProxy.canGetObject(parentId)
def getEveryCommentsUnder(self, replyToId):
# FIXME: Need to sort the ids.
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
objects = virtualServer.objects.values()
everyIds = [o.id for o in objects if o.replyToId == replyToId]
doneIds = [replyToId]
i = 0
while i < len(everyIds):
id = everyIds[i]
i += 1
if id in doneIds:
continue
doneIds.append(id)
everyIds += [o.id for o in objects if o.replyToId == id]
return [self.getObjectXmlRpc(commentId) for commentId in everyIds]
def canGetObjects(self):
return 0
def incNbReplies(self, commentId):
def getObjectIdsWithParent(self, parentId):
virtualServerId = context.getVar('applicationId')
virtualServer = self.getVirtualServer(virtualServerId)
objects = virtualServer.objects.values()
for o in objects:
if o.id==commentId:
o.nbReplies = o.nbReplies + 1
o.markAsDirty()
tempResult = []
for objectId, objectCore in virtualServer.objects.items():
if self.getParentId(objectCore) == parentId:
tempResult.append(objectId)
result = []
for objectId in tempResult:
if self.canGetObject(objectId):
result.append(objectId)
return result
def getParentId(self, comment):
currentComment = comment
while 1:
role = commonTools.extractRole(currentComment.parentId)
if role != 'comments':
return currentComment.parentId
currentComment = self.getObjectCore(currentComment.parentId)
def registerPublicMethods(self):
ObjectsServer.registerPublicMethods(self)
self.registerPublicMethod('getComments')
self.registerPublicMethod('incNbReplies')
self.registerPublicMethod('getObjectIdsWithParent')
commentsServer = CommentsServer()
if __name__ == "__main__":
if __name__ == '__main__':
commentsServer.launch(applicationName, applicationRole)

View File

@ -99,6 +99,11 @@ class GroupIntersection(GroupMixin, commonGroups.GroupIntersection):
objects.register(GroupIntersection)
class GroupRole(GroupMixin, commonGroups.GroupRole):
pass
objects.register(GroupRole)
class GroupUnion(GroupMixin, commonGroups.GroupUnion):
pass
objects.register(GroupUnion)

View File

@ -84,6 +84,29 @@ class SessionsVirtualServer(VirtualServer):
class SessionsServer(Server):
VirtualServer = SessionsVirtualServer
temporaryData = None
def addTemporaryData(self, sessionToken, data):
if not self.temporaryData:
self.temporaryData = {}
while 1:
dataToken = str(self.randomGenerator.uniform(0.1, 1))
if not self.temporaryData.has_key(dataToken):
break
self.temporaryData[sessionToken+dataToken] = data
return dataToken
def getTemporaryData(self, sessionToken, dataToken):
if not self.temporaryData or \
not self.temporaryData.has_key(sessionToken+dataToken):
return None
return self.temporaryData[sessionToken+dataToken]
def delTemporaryData(self, sessionToken, dataToken):
if not self.temporaryData or \
not self.temporaryData.has_key(sessionToken+dataToken):
return None
del self.temporaryData[sessionToken+dataToken]
def convertVirtualServersIds(self, sourceDispatcherId,
destinationDispatcherId):
@ -100,6 +123,10 @@ class SessionsServer(Server):
self.rememberOldSession(virtualServer,
virtualServer.objects[sessionToken])
del virtualServer.objects[sessionToken]
if self.temporaryData:
for k in self.temporaryData.keys():
if k.startswith(sessionToken):
del self.temporaryData[k]
virtualServer.lock.release()
virtualServer.markCoreAsDirty()
#invalidateValue(no id!)
@ -192,6 +219,9 @@ class SessionsServer(Server):
self.registerPublicMethod('getObject')
self.registerPublicMethod('newObject')
self.registerPublicMethod('setObject')
self.registerPublicMethod('addTemporaryData')
self.registerPublicMethod('getTemporaryData')
self.registerPublicMethod('delTemporaryData')
def rememberOldSession(self, virtualServer, session):
if not session.has_key('userId'):

View File

@ -58,10 +58,18 @@ class ArticleCommon(ObjectCommon):
authorsSet_kindName = 'AuthorsSet'
body = None
body_kind_balloonHelp = N_('Enter the text of the document.')
body_kind_isRequired = 1
body_kind_useCustomStorage = 1
body_kindName = 'String'
class body_kindClass:
_kindName = 'String'
balloonHelp = N_('Enter the text of the document.')
label = N_('Text')
isRequired = 1
useCustomStorage = 1
widget_colSpan = 2
widget_preview = 1
widgetName = 'TextArea'
def getTextFormat(self, slot):
return slot.getObject().format
creationTime = None
creationTime_kindName = 'CreationTime'

View File

@ -49,18 +49,8 @@ from ObjectsCommon import AdminCommon, ObjectCommon, ObjectsCommonMixin
class AdminCommentsCommon(AdminCommon):
allowAnonymousComments = 0
allowAnonymousComments_kind_isRequired = 1
allowAnonymousComments_kindName = 'Boolean'
serverRole = 'comments'
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = AdminCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['allowAnonymousComments']
return slotNames
class CommentCommon(ObjectCommon):
authorId = None
@ -72,33 +62,23 @@ class CommentCommon(ObjectCommon):
body_kind_balloonHelp = N_('Enter the text of your comment.')
body_kind_isTranslatable = 0
body_kind_isRequired = 1
body_kind_textFormat = 'spip'
body_kindName = 'String'
creationTime = None
creationTime_kind_importExport = 'from-server-only'
creationTime_kindName = 'CreationTime'
serverRole = 'comments'
replyToId = None
replyToId_kind_importExport = 'from-server-only'
replyToId_kindName = 'Id'
name = None
name_kind_balloonHelp = N_('Enter your name (if you want).')
name_kind_isRequired = 0
name_kindName = 'String'
parentId = None
parentId_kindName = 'Id'
title = None
title_kind_balloonHelp = N_('Enter the title of your comment.')
title_kind_isRequired = 1
title_kindName = 'String'
nbReplies = 0
nbReplies_kind_importExport = 'from-server-only'
nbReplies_kindName = 'Integer'
nbReplies_kind_defaultValue = 0
def canCache(self):
return 1
@ -110,7 +90,7 @@ class CommentCommon(ObjectCommon):
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = ObjectCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames += ['title', 'body', 'name', 'sourceId', 'authorId']
slotNames += ['title', 'authorId', 'body' ]
return slotNames

View File

@ -57,7 +57,7 @@ class AdminGroups(objects.AdminCommon):
class GroupAbstract(objects.ObjectCommon):
# FIME: Replace by kind ServerRoles.
# FIXME: Replace by kind ServerRoles.
acceptedRoles = None
acceptedRoles_kindName = 'AcceptedRoles'
@ -127,7 +127,8 @@ class GroupAbstract(objects.ObjectCommon):
if groupId == system.generalPublicId:
if results.has_key(groupId):
return results[groupId]
if not serverRoles or 'people' in serverRoles:
if not serverRoles or 'people' in serverRoles or \
'ldappeople' in serverRoles:
smallAndLarge = 'uncountable', 'uncountable'
else:
smallAndLarge = [], []
@ -153,8 +154,9 @@ class GroupAbstract(objects.ObjectCommon):
if groupId == system.generalPublicId:
if results.has_key(groupId):
return results[groupId]
result = not objectId \
or commonTools.extractRole(objectId) == 'people'
result = not objectId or \
commonTools.extractRole(objectId) in \
('people', 'ldappeople')
results[groupId] = result
return result
else:
@ -164,8 +166,18 @@ class GroupAbstract(objects.ObjectCommon):
class GroupCountableAbstract(GroupAbstract):
membersSet = None
membersSet_kind_itemKind_valueName = 'Id'
membersSet_kindName = 'Sequence'
class membersSet_kindClass:
_kindName = 'Sequence'
class itemKind_valueClass:
_kindName = 'Id'
def getServerRoles(self, slot):
acceptedRoles = slot.getObject().acceptedRoles
if acceptedRoles is None:
return []
if acceptedRoles == ['__all__']:
return None
return acceptedRoles
label = N_('Members')
def getOrderedLayoutSlotNames(self, parentSlot = None):
import glasnost.proxy.GroupsProxy as proxyGroups
@ -338,6 +350,25 @@ class GroupIntersection(GroupCountableAbstract):
return result
class GroupRole(GroupAbstract):
def contains2(self, objectId, indirect, results):
if self.acceptedRoles is None:
return 1
if not objectId:
return 0
role = commonTools.extractRole(objectId)
return role in self.acceptedRoles
def getContainedIds2(self, serverRoles, results):
# FIXME: not sure ?
if not serverRoles or self.acceptedRoles is None:
return 'uncountable', 'uncountable'
for acceptedRole in self.acceptedRoles:
if acceptedRole in serverRoles:
return 'uncountable', 'uncountable'
return [], []
class GroupUnion(GroupCountableAbstract):
membersSet_kind_balloonHelp = N_('Select the items of this group.')

File diff suppressed because it is too large Load Diff

View File

@ -146,10 +146,7 @@ class Aspect(things.BaseThing):
def getValues(self, slot, fields):
nameSlot = slot.getContainer().getSlot(
'name', parentSlot = slot.parent)
error, errorFields, name = nameSlot.getKind().submitField2(
nameSlot, fields)
if error:
name = None
name = nameSlot.getValue()
if name:
card = slot.getObject()
if card.hasSlotName(name):

View File

@ -66,6 +66,7 @@ def parseGlasnostLink(link):
Note that those can contains replaceable items (with replaceSpecialTags).
"""
link = link.replace('\n', ' ')
matchObject = re.match(
r'(?P<role>alias|art(icle)?|atom|book|card|election|file|'\
'grade|group|heading|im(g|age)?|person(ne)?|rubri(c|que)|'\
@ -1781,7 +1782,7 @@ def makeHtmlFromReStructuredText(text, simple = 0, inline = 0, **keywords):
self.translator_class = GlasnostHTMLTranslator
sectionLevel = 2
if keywords.has_key('sectionLevel'):
sectionLevel = int(keywords['sectionLevel'])
sectionLevel = int(keywords['sectionLevel']) - 1
self.translator_class.baseSectionLevel = sectionLevel
class GlasnostHTMLTranslator(htmlTranslator):

View File

@ -47,6 +47,8 @@ __version__ = '$Revision$'[11:-2]
import things
import glasnost.common.tools_new as commonTools
class Property(things.BaseThing):
kind = None
@ -65,6 +67,10 @@ class Property(things.BaseThing):
name_kind_label = N_('Name')
name_kindName = 'PythonIdentifier'
def getDefaultValue(self, slot):
property = commonTools.newThing('other', 'Property')
return property
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = things.BaseThing.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)

View File

@ -160,7 +160,7 @@ class BaseSlot:
def getFieldOption(self, fields, optionName, default = None):
fieldOptionName = self.getFieldOptionName(optionName)
if not fields.has_key(fieldOptionName):
if not fields or not fields.has_key(fieldOptionName):
return default
return fields[fieldOptionName]
@ -497,7 +497,10 @@ class Item(BaseSlot): # Sequence Item.
return str(self.index)
def getLocalValue(self, setIfNone = 0):
return self.getContainer(setIfNone = setIfNone)[self.index]
container = self.getContainer(setIfNone = setIfNone)
if container is None:
return None
return container[self.index]
def getPath(self):
return '%s[%s]' % (self.getContainerPath(), self.index)
@ -688,7 +691,7 @@ class Property(Attribute): # Card Property.
self.setValue(None)
def getKind(self):
# This doesn't work, because the kind would always be a commom kind.
# This doesn't work, because the kind would always be a common kind.
# import properties
# return properties.Property().newKind()
property = commonTools.newThing('other', 'Property')

View File

@ -46,4 +46,5 @@ __version__ = '$Revision$'[11:-2]
generalPublicId = 'glasnost://system/groups/1'
loggedUsersGroupId = 'glasnost://system/groups/2'

View File

@ -71,6 +71,11 @@ class GroupIntersection(objects.ObjectGtkMixin, proxyGroups.GroupIntersection):
objects.register(GroupIntersection)
class GroupRole(objects.ObjectGtkMixin, proxyGroups.GroupRole):
pass
objects.register(GroupRole)
class GroupUnion(objects.ObjectGtkMixin, proxyGroups.GroupUnion):
pass
objects.register(GroupUnion)

View File

@ -48,7 +48,7 @@ __version__ = '$Revision$'[11:-2]
from glasnost.common.CommentsCommon import *
import glasnost.common.tools_new as commonTools
from DispatcherProxy import callServer, getApplicationToken
from DispatcherProxy import MultiCall, callServer, getApplicationToken
from ObjectsProxy import register, AdminMixin, ObjectProxyMixin, ObjectsProxy
from tools import *
@ -64,36 +64,22 @@ register(Comment)
class CommentsProxy(CommentsCommonMixin, ObjectsProxy):
def getComments(self, replyToId, serverId = None):
serverId = self.getServerId(serverId = serverId)
def getObjectIdsWithParent(self, parentId, serverId = None):
userToken = context.getVar('userToken', default = '')
results = callServer(
serverId,
'getComments',
[serverId, getApplicationToken(), userToken, replyToId])
ret = []
for objectImport in results:
object = commonTools.importThing(objectImport)
ret.append(object)
return ret
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'getObjectIdsWithParent',
[serverId, getApplicationToken(), userToken, parentId])
def getObjectsWithParent(self, parentId, serverId = None):
objectIds = self.getObjectIdsWithParent(parentId, serverId = serverId)
multiCall = MultiCall()
for objectId in objectIds:
self.getObject(objectId, multiCall = multiCall)
lazyObjects = multiCall.call()
objects = {}
for i in range(len(objectIds)):
objects[objectIds[i]] = lazyObjects[i]()
return objects
def getEveryCommentsUnder(self, replyToId, serverId = None):
serverId = self.getServerId(serverId = serverId)
userToken = context.getVar('userToken', default = '')
results = callServer(
serverId,
'getEveryCommentsUnder',
[serverId, getApplicationToken(), userToken, replyToId])
ret = []
for objectImport in results:
object = commonTools.importThing(objectImport)
ret.append(object)
return ret
def incNbReplies(self, commentId, serverId = None):
serverId = self.getServerId(serverId = serverId)
userToken = context.getVar('userToken', default = '')
results = callServer(
serverId,
'incNbReplies',
[serverId, getApplicationToken(), userToken, commentId])

View File

@ -79,11 +79,17 @@ class GroupIntersection(GroupMixin, commonGroups.GroupIntersection):
objects.register(GroupIntersection)
class GroupRole(GroupMixin, commonGroups.GroupRole):
pass
objects.register(GroupRole)
class GroupUnion(GroupMixin, commonGroups.GroupUnion):
pass
objects.register(GroupUnion)
class GroupsProxy(commonGroups.GroupsCommonMixin, objects.ObjectsProxy):
def addObjectMember(self, objectId, memberId):
userToken = context.getVar('userToken', default = '')

View File

@ -1276,6 +1276,10 @@ class ObjectsProxy(ObjectsCommonMixin, AdministrableProxyMixin, Proxy):
if not objectId:
return ''
label, language = self.getObjectLabelAndLanguage(objectId)
if destinationLanguages[0] == context.getVar('readLanguages')[0] and \
language == 'en' and hasattr(_.im_self, '_catalog') and \
_.im_self._catalog.has_key(label):
return _(label)
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
labelTranslated = translationsProxy.getTranslation(
@ -1569,7 +1573,7 @@ class ObjectsProxy(ObjectsCommonMixin, AdministrableProxyMixin, Proxy):
userToken, objectExport, givenSlotNames])
return None
def newObject(self, fields):
def newObject(self, fields = None):
"""Instanciate a new object.
The class of the new object instance is stored in the *objectClassName*

View File

@ -54,6 +54,36 @@ from ObjectsProxy import Proxy
class SessionsProxy(Proxy):
serverRole = 'sessions'
def addTemporaryData(self, data, serverId = None):
userToken = context.getVar('userToken')
sessionToken = context.getVar('sessionToken')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'addTemporaryData',
[serverId, getApplicationToken(), userToken,
sessionToken, data])
def delTemporaryData(self, dataToken, serverId = None):
userToken = context.getVar('userToken')
sessionToken = context.getVar('sessionToken')
serverId = self.getServerId(serverId = serverId)
callServer(
serverId,
'delTemporaryData',
[serverId, getApplicationToken(), userToken,
sessionToken, dataToken])
def getTemporaryData(self, dataToken, serverId = None):
userToken = context.getVar('userToken')
sessionToken = context.getVar('sessionToken')
serverId = self.getServerId(serverId = serverId)
return callServer(
serverId,
'getTemporaryData',
[serverId, getApplicationToken(), userToken,
sessionToken, dataToken])
def deleteSession(self, objectToken, serverId = None):
userToken = context.getVar('userToken')
serverId = self.getServerId(serverId = serverId)

View File

@ -57,6 +57,8 @@ from ObjectsProxy import register, AdminWithoutWritersMixin, \
AdministrableProxyMixin, ObjectProxyMixin, Proxy
from tools import *
import kinds
import widgets
class AdminTranslations(AdminWithoutWritersMixin, AdminTranslationsCommon):
pass
@ -89,7 +91,7 @@ class TranslationsProxy(TranslationsCommonMixin, AdministrableProxyMixin,
'canModifyLocalization',
[serverId, getApplicationToken(), userToken, localizationKey,
sourceStringDigest])
def getLanguagesForObjectId(self, objectId):
userToken = context.getVar('userToken', default = '')
serverId = commonTools.makeApplicationId(objectId, self.serverRole)

View File

@ -92,10 +92,10 @@ class ObjectServerMixin(things.ThingMixin):
The client that want to operate on the object is usualy a other server.
"""
id_kind_isAutomaticalyModified = 1
id_kind_isAutomaticallyModified = 1
# The method id_kind_setAutomaticalValue() is defined below.
version_kind_isAutomaticalyModified = 1
version_kind_isAutomaticallyModified = 1
# The method version_kind_setAutomaticalValue() is defined below.
def __getinitargs__(self):
@ -217,7 +217,7 @@ class ObjectServerMixin(things.ThingMixin):
kind = slot.getKind()
if not kind.isModifiable:
continue
if kind.isAutomaticalyModified:
if kind.isAutomaticallyModified:
continue
if not kind.isImportable():
continue
@ -304,7 +304,7 @@ class ObjectServerMixin(things.ThingMixin):
kind = slot.getKind()
if not kind.isModifiable:
continue
if kind.isAutomaticalyModified:
if kind.isAutomaticallyModified:
kind.setAutomaticalValue(slot)
continue
if not kind.isImportable():
@ -425,7 +425,7 @@ class ObjectServerMixin(things.ThingMixin):
for slotName in self.getModifySlotNames():
slot = self.getSlot(slotName)
kind = slot.getKind()
if kind.isAutomaticalyModified:
if kind.isAutomaticallyModified:
kind.setAutomaticalValue(slot, init = 1)
def version_kind_setAutomaticalValue(self, slot, init = 0):
@ -1086,8 +1086,9 @@ class Server(things.BaseThing, applications.Application):
% applicationName)
sys.exit(1)
goDaemon()
self.setLogFile()
if not context.getVar('verbose'):
goDaemon()
self.setLogFile()
self.init()
self.load()
self.startRpcServer()

View File

@ -61,9 +61,6 @@ register(AdminAppointments)
_Appointment = Appointment
class Appointment(ObjectWebMixin, Appointment):
addToId_kindName = None
addToSlot_kindName = None
body_kind_widget_fieldLabel = N_('Text')
body_kind_widget_cols = 40
body_kind_widget_colSpan = 2
@ -689,8 +686,8 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
ul += X.li(yearLink)
return X.array(ul, self.getViewAllButtonsBarLayout())
def submitAddObject(self, object, **keywords):
result = ObjectsWebMixin.submitAddObject(self, object, **keywords)
def submitAddObject(self, object):
result = ObjectsWebMixin.submitAddObject(self, object)
if result:
return result
groupsProxy = getProxyForServerRole('groups')
@ -698,8 +695,8 @@ class AppointmentsWeb(ObjectsWebMixin, AppointmentsProxy):
groupsProxy.addObjectMember(groupId, object.id)
# what happens if it fails ?
def submitModifyObject(self, object, **keywords):
result = ObjectsWebMixin.submitModifyObject(self, object, **keywords)
def submitModifyObject(self, object):
result = ObjectsWebMixin.submitModifyObject(self, object)
if result:
return result
groupsProxy = getProxyForServerRole('groups')

View File

@ -54,7 +54,8 @@ import glasnost.common.slots as slots
from glasnost.proxy.ArticlesProxy import *
from ObjectsWeb import register, AdminMixin, ObjectWebMixin, ObjectsWebMixin
from ObjectsWeb import register, AdminMixin, ObjectWebMixin, ObjectsWebMixin, \
CommentableObjectMixin
from tools import *
@ -64,11 +65,6 @@ register(AdminArticles)
class Article(ObjectWebMixin, Article):
body_kind_widget_fieldLabel = N_('Text')
body_kind_widget_colSpan = 2
body_kind_widget_preview = 1
body_kind_widgetName = 'TextArea'
editionTime_kind_stateInEditMode = 'hidden'
editionTime_kind_widget_fieldLabel = N_('Edition Time')
editionTime_kind_widgetName = 'InputText'
@ -92,24 +88,6 @@ class Article(ObjectWebMixin, Article):
title_kind_widget_size = 40
title_kind_widgetName = 'InputText'
# this is all it takes to get a list of checkbox to select authors
#
#authorsSet_kind_widgetName = 'MultiCheck'
#authorsSet_kind_itemKind_value_valuesGetterName = 'authorsSetValues'
#
#def authorsSetValues(self, slot, fields):
# return getProxyForServerRole('people').getObjectIds()
def getEditLayout(self, fields, parentSlot = None):
formatSlot = self.getSlot('format', parentSlot = parentSlot)
formatValue = formatSlot.getField(fields, default = 'spip')
slot = self.getSlot('body', parentSlot = parentSlot)
self.body_kind = copy.copy(self.body_kind) # Deleted below.
self.body_kind.textFormat = formatValue
layout = ObjectWebMixin.getEditLayout(self, fields, parentSlot)
del self.body_kind # Created above.
return layout
def getFormattedBody(self, translate = 0):
# TODO: don't duplicate from widgets.
fieldValue = self.body
@ -125,9 +103,7 @@ class Article(ObjectWebMixin, Article):
if state not in ('translated', 'untranslatable'):
fieldValue = self.body
virtualHost = context.getVar('virtualHost')
sectionLevel = 2
if virtualHost:
sectionLevel = context.getVar('baseSectionLevel')
sectionLevel = context.getVar('sectionLevel')+1
if self.format == 'docbook':
formattedText = parsers.makeHtmlFromDocBook(fieldValue)
elif self.format == 'html':
@ -145,11 +121,11 @@ class Article(ObjectWebMixin, Article):
def getViewLayout(self, fields, parentSlot = None):
layout = X.array()
if fields.has_key('title'):
if self.title:
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
title = translationsProxy.getTranslation(
fields['title'], self.getId(), 'self.title',
self.title, self.getId(), 'self.title',
self.getLanguage(), context.getVar('readLanguages'))
else:
title = self.title
@ -157,34 +133,35 @@ class Article(ObjectWebMixin, Article):
title = ''
if parentSlot and parentSlot.getLabel() == 'Root':
context.setVar('pageTitle', title)
slot = self.getSlot('body', parentSlot = parentSlot)
self.body_kind = copy.copy(self.body_kind) # Deleted below.
self.body_kind.textFormat = self.format
if self.format == 'docbook':
#article = td # FIXME: this is obsolete
pass
else:
titlePage = X.div(_class = 'titlepage')
layout += titlePage
if not (parentSlot and parentSlot.getLabel() == 'Root') and title:
titlePage += X.h2(_class = 'title')(title)
from glasnost.proxy.GroupsProxy import getSetContainedIds
authorIds = getSetContainedIds(
self.authorsSet,
self.authorsSet_kind.itemKind.getServerRoles())
for authorId in authorIds:
titlePage += X.h3(_class = 'author')(
X.objectHypertextLabel(authorId))
slot = self.getSlot('editionTime', parentSlot = parentSlot)
titlePage += X.p(_class = 'pubdate')(
slot.getWidget().getHtmlValue(slot, fields))
sectionLevel = context.getVar('sectionLevel')
titleTag = getattr(X, 'h%s' % (sectionLevel+1))
if not (parentSlot and parentSlot.getLabel() == 'Root') and title:
layout += titleTag(_class = 'title')(title)
from glasnost.proxy.GroupsProxy import getSetContainedIds
authorIds = getSetContainedIds(
self.authorsSet,
self.authorsSet_kind.itemKind.getServerRoles(None))
authorIds = [x for x in authorIds if \
getWebForServerRole(commonTools.extractRole(x)).hasObject(x)]
meta = X.ul(_class = 'article-meta')
if authorIds:
meta += X.li(_class = 'authors')(X.asIs(
', '.join([X.objectHypertextLabel(x).getAsXml()
for x in authorIds])))
slot = self.getSlot('editionTime', parentSlot = parentSlot)
meta += X.li(_class = 'edition-time')(
slot.getWidget().getHtmlValue(slot, fields))
layout += meta
slot = self.getSlot('body', parentSlot = parentSlot)
context.push(inForm = 0)
try:
layout += slot.getWidget().getHtmlValue(slot, fields)
finally:
context.pull()
del self.body_kind # Created above.
layout += ObjectWebMixin.getViewLayout(
self, fields, parentSlot = parentSlot)
@ -209,7 +186,8 @@ class Article(ObjectWebMixin, Article):
register(Article)
class ArticlesWeb(ObjectsWebMixin, ArticlesProxy):
class ArticlesWeb(ObjectsWebMixin, CommentableObjectMixin, ArticlesProxy):
def all(self):
return ObjectsWebMixin.viewAll(self, slotNames = ['editionTime'])
all.isPublicForWeb = 1
@ -226,10 +204,6 @@ class ArticlesWeb(ObjectsWebMixin, ArticlesProxy):
article = self.getObject(id)
version = self.getObjectDiff(id, editionTime)
keywords = {}
article.makeFieldsFromInstance(keywords)
article.repairFields(keywords)
label = article.getLabelTranslated(
context.getVar('readLanguages'))
@ -323,8 +297,7 @@ class ArticlesWeb(ObjectsWebMixin, ArticlesProxy):
layout += X.buttonStandalone(
'history', X.idUrl(object.id, 'history'))
userToken = context.getVar('userToken', default = '')
if userToken and fields.has_key('format') \
and fields['format'] != 'text':
if userToken and object.format and object.format != 'text':
layout += X.buttonStandalone(
'source', X.idUrl(object.id, 'source'))
return layout
@ -380,12 +353,16 @@ class ArticlesWeb(ObjectsWebMixin, ArticlesProxy):
if not self.hasObject(id):
return pageNotFound()
article = self.getObject(id)
body = getProxyForServerRole('translations').getTranslation(
article.getBody(), article.getId(), 'self.body',
article.getLanguage(), context.getVar('readLanguages'))
label = article.getLabelTranslated(
context.getVar('readLanguages'))
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
body = translationsProxy.getTranslation(
article.getBody(), article.getId(), 'self.body',
article.getLanguage(), context.getVar('readLanguages'))
label = article.getLabelTranslated(
context.getVar('readLanguages'))
else:
body = article.body
label = article.getLabel()
layout = X.array()
layout += X.pre(_class = 'spip')(body)
@ -413,17 +390,12 @@ class ArticlesWeb(ObjectsWebMixin, ArticlesProxy):
article.lastEditorId = version['editorId']
article.editionTime = version['editionTime']
keywords = {}
article.makeFieldsFromInstance(keywords)
article.repairFields(keywords)
label = article.getLabelTranslated(
context.getVar('readLanguages'))
label = article.getLabelTranslated(context.getVar('readLanguages'))
layout = X.array()
slot = slots.Root(article)
widget = slot.getWidget()
layout += widget.getModelPageBodyLayout(slot, keywords)
layout += widget.getModelPageBodyLayout(slot, None)
return writePageLayout(layout, _('Version - %s') % label)
version.isPublicForWeb = 1

View File

@ -64,21 +64,19 @@ register(Atom)
class AtomsWeb(ObjectsWebMixin, AtomsProxy):
def submitAddObject(self, object, **keywords):
def submitAddObject(self, object):
try:
return ObjectsWebMixin.submitAddObject(self, object, **keywords)
return ObjectsWebMixin.submitAddObject(self, object)
except faults.DuplicateValue, f:
keywords['again'] = '1'
keywords['error'] = '1'
context.setVar('error', 1)
object.setError('self.name', f)
return self.edit(object = object, **keywords)
return self.editObject(object)
def submitModifyObject(self, object, **keywords):
def submitModifyObject(self, object):
try:
return ObjectsWebMixin.submitModifyObject(self, object, **keywords)
return ObjectsWebMixin.submitModifyObject(self, object)
except faults.DuplicateValue, f:
keywords['again'] = '1'
keywords['error'] = '1'
context.setVar('error', 1)
object.setError('self.name', f)
return self.edit(object = object, **keywords)
return self.editObject(object)

View File

@ -76,23 +76,21 @@ class AccountLdap(BaseObjectWebMixin, AccountLdap):
register(AccountLdap)
class AuthenticationLdapWeb(AdministrableWebMixin, AuthenticationLdapProxy):
def login(self, nextUri = '', access = '', again = '', error = '', **keywords):
return failure(
X.asIs('LDAP is not enabled in this release'), X.rootUrl())
def getMenuCommands(self):
return
def login(self, access = ''):
authObject = self.newAuthenticationObject()
return self.loginObject(authObject, access)
login.isPublicForWeb = 1
def loginObject(authObject, access = ''):
req = context.getVar('req')
req.headers_out['Cache-Control'] = 'no-cache, must-revalidate'
req.headers_out['Pragma'] = 'no-cache'
if keywords is None:
keywords = {}
authObject = self.newAuthenticationObject()
if keywords.has_key('object'):
oldAuthObject = keywords['object']
if isinstance(oldAuthObject, authObject.__class__):
authObject = oldAuthObject
authObject.login = 1
if not again:
authObject.initFields(keywords)
authObject.repairFields(keywords)
context.push(_level = 'index', layoutMode = 'edit',
authMode = 'login')
try:
@ -100,8 +98,8 @@ class AuthenticationLdapWeb(AdministrableWebMixin, AuthenticationLdapProxy):
if access == 'forbidden':
layout += X.p(_(
'To access this part of the site, you need to sign in.'))
if error:
layout += authObject.getErrorLayout(keywords)
if context.getVar('error'):
layout += authObject.getErrorLayout()
submitUrl = X.roleUrl(self.serverRole, 'loginSubmit')
if context.getVar('virtualHost').useHTTPS:
@ -116,9 +114,9 @@ class AuthenticationLdapWeb(AdministrableWebMixin, AuthenticationLdapProxy):
form += authObject.getEditLayout(keywords)
if nextUri:
if context.getVar('nextUri'):
form += X.div(X.input(name = 'nextUri', type = 'hidden',
value = nextUri))
value = context.getVar('nextUri')))
form += X.div(_class = 'buttons-bar')(
X.span(_class = 'action-buttons-bar')(
X.buttonInForm('login', 'loginButton')),
@ -126,38 +124,26 @@ class AuthenticationLdapWeb(AdministrableWebMixin, AuthenticationLdapProxy):
return writePageLayout(layout, _('Login'))
finally:
context.pull(_level = 'index')
login.isPublicForWeb = 1
def loginSubmit(self, nextUri = '', **keywords):
def loginSubmit(self, **keywords):
if keywords is None:
keywords = {}
error = 0
authObject = self.newAuthenticationObject()
if error:
keywords['again'] = 1
keywords['error'] = 1
else:
authObject.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
uri = X.roleUrl(self.serverRole, 'login')
uri.add('nextUri', nextUri)
uri.addKeywords(keywords)
return redirect(uri)
authObject.submitFields(keywords)
if context.getVar('again'):
return self.loginObject(authObject)
authWeb = getWebForServerRole('authentication')
try:
return authWeb.loginSubmitted(
'ldap', authObject, nextUri)
return authWeb.loginSubmitted('ldap', authObject)
except faults.WrongLogin, f:
keywords['again'] = '1'
keywords['error'] = '1'
context.setVar('error', 1)
authObject.setError('self.login', f)
return self.login(object = authObject, **keywords)
return self.loginObject(authObject)
except faults.WrongPassword:
keywords['again'] = '1'
keywords['error'] = '1'
context.setVar('error', 1)
authObject.setError('self.password', f)
return self.login(object = authObject, **keywords)
return self.loginObject(authObject)
except:
if context.getVar('debug'):
raise

View File

@ -110,8 +110,10 @@ class AuthenticationLibertyAllianceWeb(
return writePageLayout(
X.p('Error in Liberty Alliance authentication'), 'error')
idpAnswer.isPublicForWeb = 1
def login(self, nextUri = '', access = ''):
def login(self, access = ''):
idpUrl = 'http://localhost:8989/processAuthnRequest.html'
# TODO: get this from admin
from lvparano.Provider.ServiceProvider import ServiceProvider
sp = ServiceProvider('localhost', 8089, 8090,
SOAPEndpoint = 'http://localhost/soapEndPoint.html')

View File

@ -157,25 +157,24 @@ class ChangingUserPassword(BaseObjectWebMixin, ObjectCommon):
class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
AuthenticationLoginPasswordProxy):
def changePassword(self, again = '', error = '', **keywords):
def changePassword(self):
if not self.getAdmin().userCanChoosePassword:
return accessForbidden()
passwordChange = ChangingPassword()
if not again:
passwordChange.initFields(keywords)
passwordChange.repairFields(keywords)
return self.changePasswordObject(passwordChange)
changePassword.isPublicForWeb = 1
def changePasswordObject(self, object):
context.push(_level = 'index', layoutMode = 'edit')
try:
layout = X.array()
if error:
layout += passwordChange.getErrorLayout(keywords)
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(
action = X.actionUrl('changePasswordSubmit'),
enctype= 'multipart/form-data', method = 'post')
layout += form
form += passwordChange.getEditLayout(keywords)
form += object.getEditLayout(fields = None)
form += X.div(_class = 'buttons-bar')(
X.span(_class = 'action-buttons-bar')(
X.buttonInForm('ok', 'okButton')),
@ -183,43 +182,33 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
return writePageLayout(layout, _('Changing Password'))
finally:
context.pull(_level = 'index')
changePassword.isPublicForWeb = 1
def changePasswordSubmit(self, **keywords):
if keywords is None:
keywords = {}
if not context.getVar('userToken'):
return accessForbidden()
admin = self.getAdmin()
if not admin.userCanChoosePassword:
return accessForbidden(dontAskForLogin = 1)
if keywords is None:
keywords = {}
error = 0
passwordChange = ChangingPassword()
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
passwordChange.submitFields(keywords)
passwordChange.submitFields(keywords)
if not error:
if not context.getVar('error'):
authProxy = getProxyForServerRole('authentication')
authObject = authProxy.getAuthObject()
if authObject.password != passwordChange.currentPassword:
slot = passwordChange.getSlot('currentPassword')
slot.setFieldOption(keywords, 'error', 'wrongValue')
error = 1
passwordChange.setError(slot.getPath(), faults.BadValue)
context.setVar('error', 1)
if passwordChange.newPassword != passwordChange.new2Password:
error = 1
if error:
keywords['newPassword'] = ''
keywords['new2Password'] = ''
keywords['again'] = '1'
keywords['error'] = '1'
context.setVar('error', 1)
if keywords.has_key('again') and keywords['again']:
uri = X.actionUrl('changePassword')
uri.addKeywords(keywords)
return redirect(uri)
if context.getVar('error'):
passwordChange.newPassword = ''
passwordChange.new2Password = ''
return self.changePasswordObject(passwordChange)
authObject.password = passwordChange.newPassword
self.modifyAccount(context.getVar('userId'), authObject)
@ -230,29 +219,28 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
changePasswordSubmit.isPublicForWeb = 1
def changeUserPassword(self, account, again = '', error = '', **keywords):
def changeUserPassword(self, account):
if not self.getAdmin().userCanChoosePassword:
return accessForbidden(dontAskForLogin = 1)
if not self.isAdmin():
return accessForbidden()
if not keywords:
keywords = {}
keywords['login'] = account
passwordChange = ChangingUserPassword()
if not again:
passwordChange.initFields(keywords)
passwordChange.repairFields(keywords)
passwordChange = ChangingUserPassword()
passwordChange.login = account
return self.changeUserPasswordObject(passwordChange)
changeUserPassword.isPublicForWeb = 1
def changeUserPasswordObject(self, object):
context.push(_level = 'index', layoutMode = 'edit')
try:
layout = X.array()
if error:
layout += passwordChange.getErrorLayout(keywords)
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(
action = X.actionUrl('changeUserPasswordSubmit'),
enctype= 'multipart/form-data', method = 'post')
layout += form
form += passwordChange.getEditLayout(keywords)
form += object.getEditLayout(fields = None)
form += X.div(_class = 'buttons-bar')(
X.span(_class = 'action-buttons-bar')(
X.buttonInForm('ok', 'okButton')),
@ -260,29 +248,22 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
return writePageLayout(layout, _('Changing User Password'))
finally:
context.pull(_level = 'index')
changeUserPassword.isPublicForWeb = 1
def changeUserPasswordSubmit(self, **keywords):
if keywords is None:
keywords = {}
if not self.getAdmin().userCanChoosePassword:
return accessForbidden(dontAskForLogin = 1)
if not self.isAdmin():
return accessForbidden()
if keywords is None:
keywords = {}
error = 0
passwordChange = ChangingUserPassword()
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
passwordChange.submitFields(keywords)
passwordChange.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
uri = X.actionUrl('changeUserPassword')
uri.addKeywords(keywords)
return redirect(uri)
if context.getVar('again'):
return self.changeUserPasswordObject(passwordChange)
authObject = self.newAuthenticationObject()
authObject.login = passwordChange.login
@ -407,29 +388,25 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
return layout
def login(self, nextUri = '', access = '', again = '', error = '', **keywords):
def login(self, access = ''):
authObject = AccountLoginPassword()
return self.loginObject(authObject, access)
login.isPublicForWeb = 1
def loginObject(self, object, access = ''):
req = context.getVar('req')
req.headers_out['Cache-Control'] = 'no-cache, must-revalidate'
req.headers_out['Pragma'] = 'no-cache'
if keywords is None:
keywords = {}
authObject = AccountLoginPassword()
if keywords.has_key('object'):
oldAuthObject = keywords['object']
if isinstance(oldAuthObject, authObject.__class__):
authObject = oldAuthObject
authObject.skipPassword = 0
if not again:
authObject.initFields(keywords)
authObject.repairFields(keywords)
object.skipPassword = 0
context.push(_level = 'index', layoutMode = 'edit')
try:
layout = X.array()
if access == 'forbidden':
layout += X.p(_(
'To access this part of the site, you need to sign in.'))
if error:
layout += authObject.getErrorLayout(keywords)
if context.getVar('error'):
layout += object.getErrorLayout()
submitUrl = X.roleUrl(self.serverRole, 'loginSubmit')
if context.getVar('virtualHost').useHTTPS:
@ -442,11 +419,11 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
method = 'post')
layout += form
form += authObject.getEditLayout(keywords)
form += object.getEditLayout(fields = None)
if nextUri:
if context.getVar('nextUri'):
form += X.div(X.input(name = 'nextUri', type = 'hidden',
value = nextUri))
value = context.getVar('nextUri')))
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
buttonsBar += X.buttonInForm('login', 'loginButton')
@ -458,21 +435,17 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
context.pull(_level = 'index')
login.isPublicForWeb = 1
def loginSubmit(self, nextUri = '', **keywords):
def loginSubmit(self, **keywords):
if keywords is None:
keywords = {}
error = 0
sendPasswordByEmail = isButtonSelected('sendButton', keywords)
authObject = self.newAuthenticationObject()
if error:
keywords['again'] = 1
keywords['error'] = 1
else:
authObject.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
uri = X.roleUrl(self.serverRole, 'login')
return self.login(object = authObject, **keywords)
authObject.submitFields(keywords)
if context.getVar('again'):
return self.loginObject(authObject)
if sendPasswordByEmail:
try:
self.emailPassword(authObject)
@ -483,17 +456,15 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
authWeb = getWebForServerRole('authentication')
try:
return authWeb.loginSubmitted(
'login-password', authObject, nextUri)
'login-password', authObject)
except faults.WrongLogin, f:
keywords['again'] = '1'
keywords['error'] = '1'
context.getVar('error', 1)
authObject.setError('self.login', f)
return self.login(object = authObject, **keywords)
return self.loginObject(authObject)
except faults.WrongPassword, f:
keywords['again'] = '1'
keywords['error'] = '1'
context.getVar('error', 1)
authObject.setError('self.password', f)
return self.login(object = authObject, **keywords)
return self.loginObject(authObject)
except:
if context.getVar('debug'):
raise
@ -501,46 +472,32 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
loginSubmit.isPublicForWeb = 1
def newAccount(self, again = '', error = '', **keywords):
def newAccount(self):
usercardWeb = getProxyForServerRole('people')
if not usercardWeb.canAddObject():
return accessForbidden()
if keywords is None:
keywords = {}
userCardObject = usercardWeb.newObject(None)
if keywords.has_key('userCardObject') and \
isinstance(keywords['userCardObject'],
userCardObject.__class__):
userCardObject = keywords['userCardObject']
del keywords['userCardObject']
userCardSlot = slots.Root(userCardObject, name = 'userCard')
if not again:
userCardObject.initFields(keywords, parentSlot = userCardSlot)
userCardObject.repairFields(keywords, parentSlot = userCardSlot)
authObject = self.newAuthenticationObject()
if keywords.has_key('authObject') and \
isinstance(keywords['authObject'], authObject.__class__):
authObject = keywords['authObject']
del keywords['authObject']
if not again:
authObject.initFields(keywords)
authObject.repairFields(keywords)
return self.newAccountObject(userCardObject, authObject)
def newAccountObject(self, userCardObject, authObject):
userCardSlot = slots.Root(userCardObject, name = 'userCard')
context.push(_level = 'index', layoutMode = 'edit')
try:
layout = X.array()
if error:
layout += userCardObject.getErrorLayout(keywords)
if context.getVar('error'):
layout += userCardObject.getErrorLayout()
form = X.form(action = X.actionUrl('newAccountSubmit'),
method = 'post')
layout += form
form += userCardObject.getEditLayout(
keywords, parentSlot = userCardSlot)
form += authObject.getEditLayout(keywords)
fields = None, parentSlot = userCardSlot)
form += authObject.getEditLayout(fields = None)
form += X.div(_class = 'buttons-bar')(
X.span(_class = 'action-buttons-bar')(
@ -552,25 +509,24 @@ class AuthenticationLoginPasswordWeb(AdministrableWebMixin,
newAccount.isPublicForWeb = 1
def newAccountSubmit(self, **keywords):
if keywords is None:
keywords = {}
usercardWeb = getProxyForServerRole('people')
if not usercardWeb.canAddObject():
return accessForbidden()
if keywords is None:
keywords = {}
userCardObject = usercardWeb.newObject(None)
userCardObject = usercardWeb.newObject(fields = None)
userCardSlot = slots.Root(userCardObject, name = 'userCard')
userCardObject.submitFields(keywords, parentSlot = userCardSlot)
authObject = self.newAuthenticationObject()
authObject.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
return self.newAccount(
if context.getVar('again'):
return self.newAccountObject(
userCardObject = userCardObject,
authObject = authObject,
**keywords)
authObject = authObject)
userId = usercardWeb.addObject(userCardObject)
try:

View File

@ -61,11 +61,11 @@ import widgets
class AuthAdminWidget(widgets.Select):
def getHtmlViewValue(self, slot, fields, **keywords):
fieldValue = slot.getField(fields, default = '')
value = slot.getValue()
layout = X.array(
widgets.Select.getHtmlViewValue(self, slot, fields, **keywords),
X.buttonStandalone('settings',
X.roleUrl('authentication-'+fieldValue, 'admin')) )
X.roleUrl('authentication-'+value, 'admin')) )
return layout
register(AuthAdminWidget)
@ -103,7 +103,7 @@ class AuthenticationWeb(AdministrableWebMixin, AuthenticationProxy):
layout += X.buttonStandalone('settings', X.actionUrl('admin'))
return layout
def loginSubmitted(self, authMethod, authObject, nextUri = ''):
def loginSubmitted(self, authMethod, authObject):
userToken = self.getUserToken(authMethod, authObject)
session = context.getVar('session')
sessionToken = context.getVar('sessionToken')
@ -126,6 +126,7 @@ class AuthenticationWeb(AdministrableWebMixin, AuthenticationProxy):
context.setVar('userId', userId)
session['userToken'] = userToken
session['isDirty'] = 1
nextUri = context.getVar('nextUri') or ''
if not nextUri:
hostNameAndPort = commonTools.makeHttpHostNameAndPort(
context.getVar('httpHostName'),
@ -152,7 +153,7 @@ class AuthenticationWeb(AdministrableWebMixin, AuthenticationProxy):
context.setVar('canUseCookie', 1)
return redirect(uri)
def logout(self, nextUri = ''):
def logout(self):
authenticationProxy = getProxyForServerRole('authentication')
authenticationProxy.delUserToken()
session = context.getVar('session')
@ -175,6 +176,7 @@ class AuthenticationWeb(AdministrableWebMixin, AuthenticationProxy):
# # use
# # the cookie when loging out.
# context.setVar('canUseCookie', 0)
nextUri = context.getVar('nextUri') or ''
if not nextUri:
nextUri = '/'
else:

View File

@ -119,9 +119,6 @@ class AbstractCard(BaseObjectWebMixin, Card):
return prototype.viewModeUsersSet
return [system.generalPublicId]
def initFields(self, fields, parentSlot = None):
self.makeFieldsFromInstance(fields, parentSlot = parentSlot)
class Card(AbstractCard):
pass
@ -240,8 +237,8 @@ class CardForUse(AbstractCard):
def getC3PrototypeLinearization(self):
if self._c3PrototypeLinearization is None:
self._c3PrototypeLinearization \
= AbstractCard.getC3PrototypeLinearization(self)
self._c3PrototypeLinearization = \
AbstractCard.getC3PrototypeLinearization(self)
return self._c3PrototypeLinearization
def getSlotToModifyNames(self, parentSlot = None):
@ -276,12 +273,6 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
contentWidget = contentKind.getModelWidget(
contentSlot, forceEmbedding = 1)
keywords = {}
contentKind.makeFieldFromValue(
contentSlot, keywords, content, forceEmbedding = 1)
contentKind.repairField(contentSlot, keywords, forceEmbedding = 1)
layout = X.array()
if contentSlot.parent is not None:
@ -306,7 +297,7 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
publicPath.append(itemTitle)
layout += X.div(_class = 'public-path')(publicPath)
layout += contentWidget.getModelPageBodyLayout(contentSlot, keywords)
layout += contentWidget.getModelPageBodyLayout(contentSlot, None)
buttonsBar = X.div(_class = 'buttons-bar')
layout += buttonsBar
@ -330,78 +321,7 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
edit.isPublicForWeb = 0 # Important, so that self.parseHttpPathAction is
# called.
## def edit(self, id = '', again = '', error = '', **keywords):
## if not id:
## uri = X.actionUrl('editDefinition')
## uri.add('id', id)
## uri.addKeywords(keywords)
## return redirect(uri)
## if keywords is None:
## keywords = {}
## keywords['id'] = id
## if not self.hasObject(id):
## return pageNotFound()
## if not self.canModifyObject(id):
## return accessForbidden()
## object = self.getObject(id)
## object.__class__ = CardForUse # Important.
## rememberObject(id)
## object.execute('onEdit')
## if not again:
## object.makeFieldsFromInstance(keywords)
## object.repairFields(keywords)
## headerTitle = _('Editing %s - %s') % (
## _(self.objectNameCapitalized), object.getLabel())
## if keywords.has_key('headerTitle'):
## headerTitle = keywords['headerTitle']
## context.push(_level = 'edit',
## isCreateEditMode = not id,
## layoutMode = 'edit')
## try:
## layout = X.array()
## leadIn = self.getEditLeadIn(object, keywords)
## if leadIn:
## layout += X.enclose(leadIn, _class = 'lead-in')
## layout += object.getErrorLayout(error, keywords)
## form = X.form(action = X.actionUrl('submit'),
## enctype = 'multipart/form-data', method = 'post')
## layout += form
## if keywords.has_key('cloned') and keywords['cloned']:
## form += X.input(name = 'cloned', type = 'hidden', value = '1')
## if keywords.has_key('nextUri') and keywords['nextUri']:
## form += X.input(name = 'nextUri', type = 'hidden',
## value = keywords['nextUri'])
## slot = slots.Root(object)
## widget = slot.getWidget()
## form += widget.getModelPageBodyLayout(slot, keywords)
## buttonsBar = X.div(_class = 'buttons-bar')
## form += buttonsBar
## actionButtonsBar = X.span(_class = 'action-buttons-bar')
## buttonsBar += actionButtonsBar
## if self.canDeleteObject(id):
## actionButtonsBar += X.buttonStandalone(
## 'delete', X.idUrl(id, 'confirmDelete'))
## actionButtonsBar += X.buttonInForm('modify', 'modifyButton')
## return writePageLayout(layout, headerTitle)
## finally:
## context.pull(_level = 'edit')
## edit.isPublicForWeb = 1
def editDefinition(self, id, contentPath = '', again = '', error = '',
**keywords):
if keywords is None:
keywords = {}
keywords['id'] = id
keywords['contentPath'] = contentPath
def editDefinition(self, id, contentPath = ''):
if id and not self.hasObject(id):
return pageNotFound()
@ -413,8 +333,14 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
else:
if not self.canAddObject():
return accessForbidden()
object = self.newObject(keywords)
object = self.newObject(None)
object.__class__ = CardForDefinition # Important.
return self.editDefinitionObject(object, id, contentPath)
editDefinition.isPublicForWeb = 1
def editDefinitionObject(self, object, id = '', contentPath = ''):
try:
contentSlot = object.getSlotByPath(contentPath)
except: # FIXME.
@ -428,13 +354,6 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
contentWidget = contentKind.getModelWidget(
contentSlot, forceEmbedding = 1)
if not id and not again:
contentKind.initField(contentSlot, keywords, forceEmbedding = 1)
if id and not again:
contentKind.makeFieldFromValue(
contentSlot, keywords, content, forceEmbedding = 1)
contentKind.repairField(contentSlot, keywords, forceEmbedding = 1)
if not id:
headerTitle = _(self.newObjectNameCapitalized)
else:
@ -467,8 +386,8 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
publicPath.append(itemTitle)
layout += X.div(_class = 'public-path')(publicPath)
if error:
layout += object.getErrorLayout(keywords)
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(action = X.actionUrl('submitDefinition'),
enctype= 'multipart/form-data', method = 'post')
layout += form
@ -477,7 +396,7 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
form += X.input(name = 'contentPath', type = 'hidden',
value = contentPath)
form += contentWidget.getModelPageBodyLayout(contentSlot, keywords)
form += contentWidget.getModelPageBodyLayout(contentSlot, None)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
@ -491,7 +410,6 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
return writePageLayout(layout, headerTitle)
finally:
context.pull(_level = 'editDefinition')
editDefinition.isPublicForWeb = 1
def getViewAllActionButtonsBarLayout(self):
layout = X.array()
@ -521,52 +439,6 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
'implement', X.idUrl(object.id, 'new'))
return layout
## def implement(self, id, again = '', error = '', **keywords):
## prototypeId = id
## id = ''
## if keywords is None:
## keywords = {}
## keywords['id'] = ''
## if not self.hasObject(prototypeId):
## return pageNotFound()
## if not self.canAddObject():
## return accessForbidden()
## object = self.newObject(keywords)
## object.__class__ = CardForImplement # Important.
## object.prototypeIds = [prototypeId]
## object.execute('onCreate')
## if not again:
## object.makeFieldsFromInstance(keywords)
## object.repairFields(keywords)
## headerTitle = _('New %s') % _(self.objectNameCapitalized)
## context.push(_level = 'implement',
## isCreateEditMode = 1,
## layoutMode = 'edit')
## try:
## layout = X.array()
## layout += object.getErrorLayout(error, keywords)
## form = X.form(
## action = X.actionUrl('submitImplementation'),
## enctype = 'multipart/form-data', method = 'post')
## layout += form
## form += X.input(
## name = 'prototypeId', type = 'hidden', value = prototypeId)
## slot = slots.Root(object)
## widget = slot.getWidget()
## form += widget.getModelPageBodyLayout(slot, keywords)
## form += X.div(_class = 'buttons-bar')(
## X.span(_class = 'action-buttons-bar')(
## X.buttonInForm('create', 'createButton')))
## return writePageLayout(layout, headerTitle)
## finally:
## context.pull(_level = 'implement')
## implement.isPublicForWeb = 1
def implementations(self, id, slotNames = None):
if type(slotNames) is not types.ListType:
@ -602,12 +474,6 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
implementations.isPublicForWeb = 1
def index(self, id, modeName = '', *arguments, **keywords):
again = keywords.has_key('again') and keywords['again']
if keywords.has_key('error'):
error = keywords['error']
else:
error = ''
localId = commonTools.extractLocalId(id)
if localId.startswith('draft/'):
draftKey = localId
@ -622,6 +488,7 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
return accessForbidden()
object = self.getObject(id)
object.__class__ = CardForUse # Important.
if not modeName:
modeName = object.getDefaultModeName()
elif not object.hasMode(modeName):
@ -636,11 +503,10 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
mode.getModelUsersSet(object)):
return accessForbidden()
create = 0
command = None
if arguments:
action = arguments[0]
if action == 'new':
create = 1
prototypeId = id
id = ''
if not self.canAddObject():
@ -648,25 +514,38 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
object = self.newObject(keywords)
object.__class__ = CardForUse # Important.
object.prototypeIds = [prototypeId]
command = actions.Command()
command.action = 'create'
keywords['id'] = id
if id:
rememberObject(id)
return self.indexObject(object, mode, command)
index.isPublicForWeb = 1
def indexObject(self, object, mode, command):
modeName = mode.getName()
if modeName == 'edit':
layoutMode = 'edit'
elif modeName == 'view':
layoutMode = 'view'
else:
layoutMode = 'use'
create = 0
if command and (command.action == 'create' or
command.action == 'submit' and not object.id):
create = 1
prototypeId = object.prototypeIds[0]
context.push(_level = 'index', layoutMode = layoutMode)
try:
headerTitle, pageBodyLayout, buttonsBarLayout, inForm \
= mode.getModelLayoutInfos(object, keywords, again, create)
headerTitle, pageBodyLayout, buttonsBarLayout, inForm = \
mode.getModelLayoutInfos(object, None, create)
layout = X.array()
if inForm:
if error:
layout += object.getErrorLayout(keywords)
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(action = X.actionUrl('submit'),
enctype = 'multipart/form-data', method = 'post')
layout += form
@ -676,13 +555,6 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
if create:
form += X.input(name = 'prototypeId', type = 'hidden',
value = prototypeId)
# FIXME: Should we keep the handling of cloned and nextUri?
if keywords.has_key('cloned') and keywords['cloned']:
form += X.input(name = 'cloned', type = 'hidden',
value = '1')
if keywords.has_key('nextUri') and keywords['nextUri']:
form += X.input(name = 'nextUri', type = 'hidden',
value = keywords['nextUri'])
form += pageBodyLayout
if buttonsBarLayout:
form += buttonsBarLayout
@ -698,7 +570,6 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
return layout
finally:
context.pull(_level = 'index')
index.isPublicForWeb = 1
def parseHttpPathAction(self, remaining):
context.push()
@ -769,11 +640,10 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
def submit(self, id = '', modeName = '', prototypeId = '', **keywords):
if keywords is None:
keywords = {}
keywords['id'] = id
keywords['id'] = id # FIXME: not sure it is still useful
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
error = 0
context.setVar('again', 1)
context.setVar('hideErrors', 1)
removeDraft = 0
if id:
@ -802,24 +672,26 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
mode.getModelUsersSet(object)):
return accessForbidden()
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
command = actions.Command()
command.action = 'submit'
command.nextObjectId = id
context.push(_level = 'submit',
command = command)
try:
mode.submitModelFields(object, keywords)
finally:
command = context.getVar('command')
context.pull(_level = 'submit')
if keywords.has_key('again') and keywords['again']:
uri = X.idUrl(id, modeName)
uri.addKeywords(keywords)
return redirect(uri)
command = actions.Command()
command.action = 'submit'
command.nextObjectId = id
context.push(_level = 'submit',
command = command)
try:
mode.submitModelFields(object, keywords)
finally:
# I don't like this; why is the submit in its own context ?
again = context.getVar('again')
error = context.getVar('error')
command = context.getVar('command')
context.pull(_level = 'submit')
if again:
context.setVar('again', 1)
if error:
context.setVar('error', 1)
if context.getVar('again'):
return self.indexObject(object, mode, command)
mode.executeModel(object, 'onSubmit', command)
action = command.action
if action == 'create' or action == 'submit' and not id:
@ -837,12 +709,10 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
try:
self.modifyPartialObject(object, slotToModifyNames)
except faults.WrongVersion:
keywords['again'] = '1'
keywords['error'] = '1'
keywords['versionError'] = '1'
uri = X.idUrl(id, modeName)
uri.addKeywords(keywords)
return redirect(uri)
context.setVar('again', 1)
context.setVar('error', 1)
object.setError('version', 1)
return self.indexObject(object, mode, command)
except:
if context.getVar('debug'):
raise
@ -904,9 +774,8 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
keywords['id'] = id
keywords['contentPath'] = contentPath
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
error = 0
context.setVar('again', 1)
context.setVar('hideErrors', 1)
if id:
object = self.getObject(id)
@ -923,17 +792,13 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
contentSlot = slots.Root(object)
content = contentSlot.getValue()
contentKind = contentSlot.getKind()
contentWidget = contentSlot.getWidget()
contentWidget.submitEmbedded(contentSlot, keywords)
if context.getVar('again'):
return self.editDefinitionObject(object, contentPath)
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
contentKind.submitField(contentSlot, keywords, forceEmbedding = 1)
if keywords.has_key('again') and keywords['again']:
uri = X.idUrl(id, 'editDefinition/%s' % contentPath)
del keywords['contentPath']
uri.addKeywords(keywords)
return redirect(uri)
if not id:
try:
id = self.addObject(object)
@ -945,13 +810,10 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
try:
self.modifyPartialObject(object, object.getSlotToModifyNames())
except faults.WrongVersion:
keywords['again'] = '1'
keywords['error'] = '1'
keywords['versionError'] = '1'
uri = X.idUrl(id, 'editDefinition/%s' % contentPath)
del keywords['contentPath']
uri.addKeywords(keywords)
return redirect(uri)
context.setVar('again', 1)
context.setVar('error', 1)
object.setError('version', 1)
return self.editDefinitionObject(object, contentPath)
except:
if context.getVar('debug'):
raise
@ -959,37 +821,6 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
return redirect(X.idUrl(id, 'definition/%s' % contentPath))
submitDefinition.isPublicForWeb = 1
## def submitImplementation(self, prototypeId, **keywords):
## if keywords is None:
## keywords = {}
## keywords['id'] = ''
## if isButtonSelected('applyButton', keywords):
## keywords['again'] = '1'
## keywords['hideErrors'] = '1'
## error = 0
## object = self.newObject(keywords)
## object.__class__ = CardForImplement # Important.
## object.prototypeIds = [prototypeId]
## if error:
## keywords['again'] = '1'
## keywords['error'] = '1'
## else:
## object.submitFields(keywords)
## if keywords.has_key('again') and keywords['again']:
## uri = X.idUrl(prototypeId, 'implement')
## uri.addKeywords(keywords)
## return redirect(uri)
## try:
## id = self.addObject(object)
## except faults.Fault:
## if context.getVar('debug'):
## raise
## return accessForbidden()
## return redirect(X.idUrl(id))
## submitImplementation.isPublicForWeb = 1
def use(self, *arguments, **keywords):
pass
use.isPublicForWeb = 0 # Important, so that self.parseHttpPathAction is
@ -1000,44 +831,3 @@ class CardsWeb(ObjectsWebMixin, CardsProxy):
view.isPublicForWeb = 0 # Important, so that self.parseHttpPathAction is
# called.
## def view(self, id):
## if not self.hasObject(id):
## return pageNotFound()
## if not self.canGetObject(id):
## return accessForbidden()
## object = self.getObject(id)
## object.__class__ = CardForUse # Important.
## rememberObject(id)
## object.execute('onView')
## keywords = {}
## object.makeFieldsFromInstance(keywords)
## object.repairFields(keywords)
## label = object.getLabelTranslated(context.getVar('readLanguages'))
## layout = X.array()
## leadIn = self.getViewLeadIn(object, keywords)
## if leadIn:
## layout += X.enclose(leadIn, _class = 'lead-in')
## slot = slots.Root(object)
## widget = slot.getWidget()
## layout += object.getViewLayout(fields, parentSlot = None)
## layout += widget.getModelPageBodyLayout(slot, keywords)
## pageTitle = context.getVar('pageTitle', default = None)
## layout += self.getViewAboveButtonsBarLayout(object, keywords)
## if context.getVar('userId'):
## layout += self.getViewButtonsBarLayout(object, keywords)
## layout += self.getViewBelowButtonsBarLayout(object, keywords)
## context.push(
## currentObject = WebAPI.GlasnostObject(object = object),
## )
## if not pageTitle:
## pageTitle = '%s - %s' % (_(self.objectNameCapitalized), label)
## layout = writePageLayout(layout, pageTitle)
## context.pull()
## return layout
## view.isPublicForWeb = 1

View File

@ -54,17 +54,11 @@ from tools import *
class AdminComments(AdminMixin, AdminComments):
allowAnonymousComments_kind_widget_fieldLabel = N_(
'Allow Anonymous Comments')
allowAnonymousComments_kind_widgetName = 'InputCheckBox'
pass
register(AdminComments)
class Comment(ObjectWebMixin, Comment):
authorId_kind_stateInEditMode = 'hidden'
authorId_kind_widget_fieldLabel = N_('Author')
authorId_kind_widgetName = 'SelectId'
body_kind_widget_fieldLabel = N_('Text')
body_kind_widget_cols = 75
body_kind_widget_colSpan = 2
@ -72,124 +66,76 @@ class Comment(ObjectWebMixin, Comment):
body_kind_widget_rows = 20
body_kind_widgetName = 'TextArea'
creationTime_kind_stateInEditMode = 'hidden'
language_kind_stateInEditMode = 'hidden'
name_kind_widget_fieldLabel = N_('Name')
name_kind_widget_size = 40
name_kind_widgetName = 'InputText'
nbReplies_kind_stateInEditMode = 'hidden'
title_kind_widget_fieldLabel = N_('Title')
title_kind_widget_size = 40
title_kind_widgetName = 'InputText'
replyToId_kind_stateInEditMode = 'hidden'
replyToId_kind_widget_fieldLabel = N_('Commented Item')
replyToId_kind_widgetName = 'SelectId'
def getEditLayoutHiddenSlotNames(self, fields, parentSlot = None):
hiddenSlotNames = ObjectWebMixin.getEditLayoutHiddenSlotNames(
self, fields, parentSlot = parentSlot)
hiddenSlotNames = hiddenSlotNames[:]
userToken = context.getVar('userToken', default = '')
if userToken:
hiddenSlotNames += ['name']
return hiddenSlotNames
def getEditLayoutSlotNames(self, fields, parentSlot = None):
slotNames = ObjectWebMixin.getEditLayoutSlotNames(self, fields,
parentSlot = parentSlot) [:]
if 'authorId' in slotNames:
slotNames.remove('authorId')
if 'parentId' in slotNames:
slotNames.remove('parentId')
if 'creationTime' in slotNames:
slotNames.remove('creationTime')
return slotNames
def getViewLayoutSlotNames(self, fields, parentSlot = None):
return ['title', 'body']
def getViewLayout(self, fields, parentSlot = None):
sectionLevel = context.getVar('sectionLevel')
context.push(sectionLevel = sectionLevel+1)
def render(self):
layout = X.array()
layout += X.h4(self.getLabel())
commentInfos = X.div(_class = 'comment-infos')
layout += commentInfos
if self.authorId:
commentInfos += X.span(_class = 'comment-author')( \
X.objectHypertextLabel(self.authorId))
elif self.name:
commentInfos += X.span(_class = 'comment-author')(self.name)
else:
commentInfos += X.span(_class = 'comment-author')(_('Anonymous'))
if self.creationTime:
value = time.strftime('%Y-%m-%d %H:%M:%S',
time.localtime(self.creationTime))
commentInfos += X.span(_class = 'comment-time')(value)
layout += X.asIs(replaceSpecialTags(
parsers.makeHtmlFromSpip(self.body)))
return layout
titleSlot = self.getSlot('title')
titleHtml = titleSlot.getWidget().getHtmlValue(titleSlot, fields)
titleTag = getattr(X, 'h%s' % (sectionLevel+1))
if len(titleHtml.children) == 2:
# remove translation bar
del titleHtml.children[1]
layout += titleTag(titleHtml)
authorIdSlot = self.getSlot('authorId')
if authorIdSlot.getValue():
layout += X.span(_class = 'authorId')(
authorIdSlot.getWidget().getHtmlValue(authorIdSlot, fields))
else:
layout += X.span(_class = 'authorId')(_('Anonymous'))
creationTimeSlot = self.getSlot('creationTime')
layout += X.span(_class = 'creationTime')(
creationTimeSlot.getWidget().getHtmlValue(creationTimeSlot, fields))
bodySlot = self.getSlot('body')
layout += X.div(bodySlot.getWidget().getHtmlValue(bodySlot, fields))
context.pull()
return layout
register(Comment)
class CommentsWeb(ObjectsWebMixin, CommentsProxy):
def edit(self, id = '', again = '', error = '', **keywords):
userToken = context.getVar('userToken', default = '')
if not userToken:
return pageNotFound()
return ObjectsWebMixin.edit(self, id, again, error, **keywords)
edit.isPublicForWeb = 1
def clone(self): pass
def confirmDelete(self): pass
def delete(self): pass
def download(self): pass
def edit(self): pass
def id(self): pass
def image(self): pass
def imageEdit(self): pass
def rss(self): pass
def search(self): pass
def submit(self): pass
def thumbnail(self): pass
def use(self): pass
def view(self): pass
def postXml(self, id):
if not context.getVar('xmlPost'):
return pageNotFound()
xmlPost = context.getVar('xmlPost')
item = xmlPost.firstChild
dict = convertNodesToDict(item.childNodes)
title = author = description = link = source = ''
if dict.has_key('title'):
title = dict['title']
if dict.has_key('author'):
author = dict['author']
if dict.has_key('description'):
description = dict['description']
if dict.has_key('link'):
link = dict['link']
if dict.has_key('source'):
source = dict['source']
comment = commonTools.newThing('object', 'comments.Comment')
comment.body = description
comment.replyToId = id
comment.name = author
comment.title = title
if context.getVar('virtualHost'):
comment.language = context.getVar('virtualHost').language
else:
comment.language = 'en'
try:
commentId = self.addObject(comment)
except faults.Fault:
if context.getVar('debug'):
raise
return accessForbidden()
return writePageLayout(X.array(), 'Comment API')
postXml.isPublicForWeb = 1
def submit(self, id = '', **keywords):
userToken = context.getVar('userToken', default = '')
if not userToken:
return pageNotFound()
return ObjectsWebMixin.submit(self, id, **keywords)
submit.isPublicForWeb = 1
def view(self, id):
if not self.hasObject(id):
return pageNotFound()
if not self.canGetObject(id):
return accessForbidden()
object = self.getObject(id)
layout = object.render()
return writePageLayout(layout, '%s' % _(self.objectNameCapitalized))
view.isPublicForWeb = 1
def viewAll(self):
userToken = context.getVar('userToken', default = '')
if not userToken:
return pageNotFound()
return ObjectsWebMixin.viewAll(self)
layout = X.array()
userToken = context.getVar('userToken')
if self.canModifyAdmin() and userToken:
layout += X.div(_class = 'buttons-bar')(
X.buttonStandalone('settings', X.actionUrl('admin')))
return writePageLayout(layout, _(self.objectsNameCapitalized))
viewAll.isPublicForWeb = 1

View File

@ -94,7 +94,7 @@ class ElectionMixin(ObjectWebMixin):
method = None
method_kind_defaultValue = 'condorcet'
method_kind_hasToMakeFieldFromValue = 0
#method_kind_hasToMakeFieldFromValue = 0
method_kind_isRequired = 1
method_kind_values = [
'average',
@ -185,12 +185,11 @@ class ElectionMixin(ObjectWebMixin):
readOnlySlotNames = ObjectWebMixin.getEditLayoutReadOnlySlotNames(
self, fields, parentSlot = parentSlot)
readOnlySlotNames = readOnlySlotNames[:]
state = fields['state']
if not fields.has_key('id') or not fields['id']:
if not self.id:
slotName = 'state'
if not slotName in readOnlySlotNames:
readOnlySlotNames.append(slotName)
if state in ['closed', 'running']:
if self.state in ['closed', 'running']:
for slotName in [
'ballotKind', 'candidatesSet', 'method', 'subject', 'title',
'voteKind', 'votersSet', 'weightingsGradeId']:
@ -371,14 +370,6 @@ class ElectionMixin(ObjectWebMixin):
tr += vote.getMarksRowLayout(candidateIds)
return layout
def makeFieldsFromInstance(self, fields, parentSlot = None):
if self.__class__ == ElectionAverage:
fields['method'] = 'average'
else:
fields['method'] = 'condorcet'
ObjectWebMixin.makeFieldsFromInstance(
self, fields, parentSlot = parentSlot)
def newVote(self):
vote = commonTools.newThing('object', 'votes.%s' % self.voteKind)
if self.ballotKind != 'voter-choice':
@ -604,7 +595,6 @@ class ElectionCondorcet(ElectionMixin, ElectionCondorcet):
table += X.colgroup()
table += X.colgroup(span = 3)
table += X.thead(X.tr(
# FIXME: I don't know which scope to apply to this <th>
X.th()(_('Candidates')),
X.th(scope = 'col')(_('Wins')),
X.th(scope = 'col')(_('Losses')),
@ -669,15 +659,10 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
if not self.canCloneObject(id):
return accessForbidden()
object = self.getObject(id)
object.id = None
object.version = 0
object.state = 'draft' # The difference is here.
keywords = {}
object.makeFieldsFromInstance(keywords)
del keywords['id']
keywords['again'] = 1
keywords['cloned'] = 1
uri = X.actionUrl('edit')
uri.addKeywords(keywords)
return redirect(uri)
return self.editObject(object)
clone.isPublicForWeb = 1
def confirmPesterAbstentionnists(self, id):
@ -699,6 +684,15 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
canCache = 0)
confirmPesterAbstentionnists.isPublicForWeb = 1
def getObject_handleResult(self, lazyObject):
object = ElectionsProxy.getObject_handleResult(self,
lazyObject)
if self.__class__ is ElectionAverage:
object.getSlot('method').setValue('average')
else:
object.getSlot('method').setValue('condorcet')
return object
def getViewBelowButtonsBarLayout(self, object, fields):
layout = X.div(_class = 'election-results')
layout += ObjectsWebMixin.getViewBelowButtonsBarLayout(
@ -776,8 +770,9 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
return OK
graphPie.isPublicForWeb = 1
def newObject(self, fields):
if fields.has_key('method') and fields['method'] == 'average':
def newObject(self, fields = None):
if fields and fields.has_key('method') and \
fields['method'] == 'average':
object = ElectionAverage()
else:
object = ElectionCondorcet()
@ -800,18 +795,13 @@ class ElectionsWeb(ObjectsWebMixin, ElectionsProxy):
X.idUrl(id))
pesterAbstentionnists.isPublicForWeb = 1
def submitAddObject(self, object, **keywords):
def submitAddObject(self, object):
try:
return ObjectsWebMixin.submitAddObject(self, object, **keywords)
return ObjectsWebMixin.submitAddObject(self, object)
except faults.WinnersGroupNotEmpty, f:
keywords['again'] = '1'
keywords['error'] = '1'
context.setVar('error', 1)
object.setError('self.winnersGroupId', f)
return self.editObject(object, **keywords)
keywords['winnersGroupId_error'] = _('Group not empty!')
uri = X.idUrl(object.id, 'edit')
uri.addKeywords(keywords)
return redirect(uri)
return self.editObject(object)
def view(self, id):
if not self.hasObject(id):

View File

@ -75,254 +75,5 @@ register(Forum)
class ForumsWeb(ObjectsWebMixin, ForumsProxy):
def addComment(self, id, replyToId = '', again = '', error = '',
**keywords):
if not self.hasObject(id):
return pageNotFound()
forum = self.getObject(id)
if keywords is None:
keywords = {}
keywords['id'] = id
if replyToId:
keywords['replyToId'] = replyToId
else:
keywords['replyToId'] = id
keywords['language'] = forum.language
userId = context.getVar('userId', '')
if userId:
keywords['authorId'] = userId
if not self.hasObject(id):
return pageNotFound()
commentsWeb = getWebForServerRole('comments')
comment = commonTools.newThing('object', 'comments.Comment')
if not again:
comment.initFields(keywords)
comment.repairFields(keywords)
context.push(_level = 'addComment',
isCreateEditMode = 1,
layoutMode = 'edit')
try:
layout = X.array()
if error:
layout += comment.getErrorLayout(keywords)
form = X.form(
action = X.actionUrl('submitComment'),
enctype= 'multipart/form-data',
method = 'post', replyToId = replyToId)
layout += form
slot = slots.Root(comment)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, keywords)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
actionButtonsBar = X.span(_class = 'action-buttons-bar')
buttonsBar += actionButtonsBar
actionButtonsBar += X.buttonInForm('create', 'createButton')
return writePageLayout(layout, _('New Comment'))
finally:
context.pull(_level = 'addComment')
addComment.isPublicForWeb = 1
def submitComment(self, id, **keywords):
if keywords is None:
keywords = {}
keywords['id'] = id
forum = self.getObject(id)
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
error = 0
commentsWeb = getWebForServerRole('comments')
if keywords.has_key('replyToId') and keywords['replyToId']:
commentsWeb.incNbReplies(keywords['replyToId'])
comment = commonTools.newThing('object', 'comments.Comment')
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
del keywords['id'] # Not the comment id.
comment.submitFields(keywords)
comment.language = forum.language
if keywords.has_key('again') and keywords['again']:
uri = X.idUrl(id, 'addComment')
uri.addKeywords(keywords)
return redirect(uri)
try:
commentId = commentsWeb.addObject(comment)
except faults.Fault:
raise
return accessForbidden()
return redirect(X.idUrl(id))
submitComment.isPublicForWeb = 1
def renderReplies(self, forumId, commentId):
userToken = context.getVar('userToken', default = '')
layout = X.array()
# add quick path :
layout += X.a(href = X.actionUrl())('Index Forums')
layout += ' -> '
# ... and build the forum link :
object = getObject(forumId)
layout += X.a(href = X.idUrl(forumId))(object.title)
# render original comment :
commentsWeb = getWebForServerRole('comments')
comment = commentsWeb.getObject(commentId)
layout += comment.render()
# comment add button :
if userToken:
layout += X.buttonStandalone('post-reply',
X.idUrl(forumId, 'addComment').add('replyToId', commentId))
# render replies :
layout += X.h4(_('replies: %d') % comment.nbReplies)
comments = commentsWeb.getComments(replyToId = commentId)
for comment in comments:
layout += X.hr()
layout += comment.render()
return writePageLayout(layout, _('Replies List'))
renderReplies.isPublicForWeb = 1
def getViewActionButtonsBarLayout(self, object, fields):
layout = ObjectsWebMixin.getViewActionButtonsBarLayout(
self, object, fields)
layout += X.array()
layout += X.br()
layout += X.br()
# add post button (new subject ) :
userToken = context.getVar('userToken', default = '')
if object.isActive:
if userToken:
layout += X.buttonStandalone(
'post-comment', X.idUrl(object.id, 'addComment'))
# add quick path :
layout += X.a(href = X.actionUrl())('Index Forums')
return layout
def getViewNavigationButtonsBarLayout(self, object, fields):
pass
def getViewOtherActionButtonsBarLayout(self, object, fields):
pass
def view(self, id):
# render the subjects/comments of the forum :
userToken = context.getVar('userToken', default = '')
if not self.hasObject(id):
return pageNotFound()
if not self.canGetObject(id):
return accessForbidden()
object = Forum()
slotNames = [x for x in object.getSlotNames()]
object = self.getPartialObject(id, slotNames)
rememberObject(id)
keywords = {}
object.makeFieldsFromInstance(keywords)
object.repairFields(keywords)
layout = X.array()
# button bar :
layout += self.getViewActionButtonsBarLayout(object, keywords)
# index link :
if not userToken:
layout += X.div(_class = 'indexForum')
layout += X.a(href = X.actionUrl())('Index Forums')
commentsWeb = getWebForServerRole('comments')
comments = commentsWeb.getComments(replyToId = id)
if comments:
# FIXME: probably not xhtml strict (there are other
# cases in this file, pay attention)
table = X.table(width="100%", cellspacing="2", cellpadding="2",
border="0", align="center")
tr = X.tr()
tr += X.th()(_('Subject'))
tr += X.th()(_('Replies'))
tr += X.th()(_('Author'))
table += tr
for comment in comments:
tr = X.tr()
tr += X.td(width = "65%", align = "left")(X.a(
href = X.idUrl(id, 'renderReplies').add(
'forumId', id).add('commentId', comment.id))(
comment.title))
tr += X.td(align = "center")(comment.nbReplies)
if comment.authorId:
tr += X.td(align = "center")(
X.objectHypertextLabel(comment.authorId))
elif comment.name:
tr += X.td(align = "center")(comment.name)
else:
tr += X.td(align = "center")(comment.body)
table += tr
layout += table
return writePageLayout(layout, '%s' % object.title)
view.isPublicForWeb = 1
def getIndexForumLayout(self):
forumsWeb = getWebForServerRole('forums')
forums = forumsWeb.getForums()
layout = X.array()
if len(forums)>0:
table = X.table(width="100%", cellspacing="2",
cellpadding="2", border="0", align="center")
tr = X.tr()
tr += X.th()(_('Forum'))
tr += X.th()(_('Active'))
tr += X.th()(_('Subjects'))
table += tr
for p in forums:
commentsWeb = getWebForServerRole('comments')
comments = commentsWeb.getComments(replyToId = p.id)
nb_subjects = len(comments)
tr = X.tr()
tr += X.td(align="left")(X.a(href = X.idUrl(p.id))(p.title))
if p.isActive:
isActive = _('Yes')
else:
isActive = _('No')
tr += X.td(align="center")(isActive)
tr += X.td(align="center")(nb_subjects)
table += tr
layout += table
layout += X.br()
layout += ObjectsWebMixin.getViewAllActionButtonsBarLayout(self)
return layout
def viewAll(self):
context.push(_level = 'viewAll',
defaultDispatcherId = context.getVar('dispatcherId'))
try:
layout = self.getIndexForumLayout()
finally:
context.pull(_level = 'viewAll')
return writePageLayout(layout, _('Forums List'))
viewAll.isPublicForWeb = 1
pass

View File

@ -93,10 +93,10 @@ class MarksWidget(widgets.BaseWidget):
else:
td = X.td(_class = 'field-value')
tr += td
errorCode = slot.getFieldOption(
fields, objectId + '_error')
if errorCode and not fields.has_key('hideErrors'):
td += X.asIs(makeErrorMessage(errorCode))
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
td += X.input(maxlength = 6, name = fieldName, size = 6,
type = 'text', value = mark)
td += X.nbsp
@ -146,7 +146,7 @@ class Grade(ObjectWebMixin, Grade):
value = []
for i in range(count):
itemSlot = kind.getItemSlot(slot, i)
itemValue = itemSlot.getField(fields, default = '')
itemValue = itemSlot.getValue() or ''
if itemValue:
value.append(itemValue)
if value == []:

View File

@ -63,7 +63,7 @@ objects.register(AdminGroups)
class GroupMixin(objects.ObjectWebMixin):
# FIME: Replace by kind ServerRoles.
# FIXME: Replace by kind ServerRoles.
acceptedRoles_kind_itemKind_value_widget_allLabel = N_('Every Type')
acceptedRoles_kind_itemKind_value_widget_noneLabel = N_('No Type')
acceptedRoles_kind_widget_apply = 1
@ -71,8 +71,6 @@ class GroupMixin(objects.ObjectWebMixin):
className = None
className_kind_defaultValue = 'GroupUnion'
className_kind_hasToMakeFieldFromValue = 0
className_kind_hasToSubmitField = 0
className_kind_importExport = 'private'
className_kind_isRequired = 1
className_kind_values = [
@ -106,26 +104,6 @@ class GroupMixin(objects.ObjectWebMixin):
slotNames.remove(slotName)
return slotNames
def initFields(self, fields, parentSlot = None):
fields['className'] = self.__class__.__name__
objects.ObjectWebMixin.initFields(
self, fields, parentSlot = parentSlot)
def makeFieldsFromInstance(self, fields, parentSlot = None):
fields['className'] = self.__class__.__name__
objects.ObjectWebMixin.makeFieldsFromInstance(
self, fields, parentSlot = parentSlot)
def repairFields(self, fields, parentSlot = None):
if fields.has_key('className'):
self.__class__ = commonTools.getThingClass(
'object', 'groups.%s' % fields['className'])
else:
self.__class__ = commonTools.getThingClass(
'object', 'groups.GroupUnion')
objects.ObjectWebMixin.repairFields(
self, fields, parentSlot = parentSlot)
class GroupCountableMixin(GroupMixin):
itemIds = None
@ -137,30 +115,6 @@ class GroupCountableMixin(GroupMixin):
itemIds_kind_widgetName = 'Multi'
itemIds_kindName = 'Sequence'
membersSet_kind_itemKind_value_widgetName = 'SelectId'
membersSet_kind_widget_fieldLabel = N_('Members')
membersSet_kind_widgetName = 'Multi'
def getEditLayout(self, fields, parentSlot = None):
acceptedRolesSlot = self.getSlot(
'acceptedRoles', parentSlot = parentSlot)
# Duplicates fields, so that the "missing value" error fields generated
# by the following submitField are not displayed.
tmpFields = fields.copy()
acceptedRolesSlot.getKind().submitField(acceptedRolesSlot, tmpFields)
acceptedRoles = self.acceptedRoles
if acceptedRoles:
self.membersSet_kind = copy.copy(self.membersSet_kind)
self.membersSet_kind.itemKind = copy.copy(
self.membersSet_kind.itemKind)
self.membersSet_kind.itemKind.serverRoles = acceptedRoles
layout = GroupMixin.getEditLayout(
self, fields, parentSlot = parentSlot)
if acceptedRoles:
del(self.membersSet_kind.itemKind)
del(self.membersSet_kind)
return layout
def getEditLayoutSlotNames(self, fields, parentSlot = None):
slotNames = GroupMixin.getEditLayoutSlotNames(
self, fields, parentSlot = parentSlot)
@ -181,23 +135,6 @@ class GroupCountableMixin(GroupMixin):
slotNames.remove(slotName)
return slotNames
def makeFieldsFromInstance(self, fields, parentSlot = None):
self.itemIds_kind = None
GroupMixin.makeFieldsFromInstance(
self, fields, parentSlot = parentSlot)
del self.itemIds_kind
try:
self.itemIds = self.getContainedIds()
except faults.IllegalRecursiveGroup:
self.itemIds_kind = commonTools.newThing(
'kind', 'String', isTranslatable = 0)
self.itemIds = _('Illegal recursive group')
else:
self.itemIds = sortIds(self.itemIds)
slot = self.getSlot('itemIds', parentSlot = parentSlot)
kind = self.itemIds_kind
kind.makeFieldFromValue(slot, fields, self.itemIds)
class GroupAll(GroupMixin, proxyGroups.GroupAll):
pass
@ -214,20 +151,44 @@ class GroupIntersection(GroupCountableMixin, proxyGroups.GroupIntersection):
objects.register(GroupIntersection)
class GroupRole(GroupMixin, proxyGroups.GroupRole):
pass
objects.register(GroupRole)
class GroupUnion(GroupCountableMixin, proxyGroups.GroupUnion):
pass
objects.register(GroupUnion)
class GroupsWeb(objects.ObjectsWebMixin, proxyGroups.GroupsProxy):
def newObject(self, fields):
if fields.has_key('className'):
object = commonTools.newThing(
'object', 'groups.%s' % fields['className'])
else:
object = commonTools.newThing('object', 'groups.GroupUnion')
def getObject_handleResult(self, lazyObject):
object = proxyGroups.GroupsProxy.getObject_handleResult(self,
lazyObject)
object.className = object.__class__.__name__
if hasattr(object, 'itemIds'): # group is countable
try:
object.itemIds = object.getContainedIds()
object.itemIds = sortIds(object.itemIds)
except faults.IllegalRecursiveGroup:
object.itemIds_kind = commonTools.newThing(
'kind', 'String', isTranslatable = 0)
object.itemIds = _('Illegal recursive group')
return object
def newObject(self, fields = None):
group = GroupUnion() # fake group to get className
if not fields:
group.className = 'GroupUnion'
return group
classNameSlot = group.getSlot('className')
className = classNameSlot.getWidget().submit(classNameSlot, fields)
if not className:
className = 'GroupUnion'
group = commonTools.newThing('object', 'groups.%s' % className)
group.className = className
return group
def view(self, id):
webTools.addContextualHeader('noindex')
return objects.ObjectsWebMixin.view(self, id)

View File

@ -84,10 +84,7 @@ class BaseObjectWebMixin(things.ThingMixin):
version_kind_widgetName = 'InputText'
def getEmbeddedViewLayout(self):
fields = {}
self.makeFieldsFromInstance(fields)
self.repairFields(fields)
return self.getCompactViewLayout(fields, parentSlot = None)
return self.getCompactViewLayout(None, parentSlot = None)
def getLabelTranslated(self, destinationLanguages = None, multiCall = None):
translationsProxy = getProxyForServerRole('translations')
@ -145,39 +142,8 @@ class AdminMixin(AdminWithoutWritersMixin):
class ObjectWebMixin(BaseObjectWebMixin):
addToId = None
addToId_kind_stateInEditMode = 'read-only'
addToId_kind_widget_fieldLabel = N_('Added to')
addToId_kind_widgetName = 'SelectId'
addToId_kindName = 'Id'
addToSlot = None
addToSlot_kind_stateInEditMode = 'hidden'
addToSlot_kind_stateInViewMode = 'hidden'
addToSlot_kind_widget_fieldLabel = N_('Added to slot')
addToSlot_kindName = 'String'
def getViewLayoutSlotNames(self, fields, parentSlot = None):
slotNames = BaseObjectWebMixin.getViewLayoutSlotNames(
self, fields, parentSlot = parentSlot)
if 'addToId' in slotNames:
slotNames.remove('addToId')
if 'addToSlot' in slotNames:
slotNames.remove('addToSlot')
return slotNames
def getEditLayoutSlotNames(self, fields, parentSlot = None):
slotNames = BaseObjectWebMixin.getEditLayoutSlotNames(
self, fields, parentSlot = parentSlot)
if 'addToId' in slotNames:
slotNames.remove('addToId')
if 'addToSlot' in slotNames:
slotNames.remove('addToSlot')
if fields.has_key('addToId') and fields['addToId'] and \
not (fields.has_key('id') and fields['id']):
slotNames.insert(0, 'addToId')
slotNames.insert(0, 'addToSlot')
return slotNames
# this class had methods to add an object to another
pass
class WebMixin(things.ThingMixin):
@ -193,12 +159,8 @@ class AdministrableWebMixin(WebMixin):
return accessForbidden()
admin = self.getAdmin()
keywords = {}
admin.makeFieldsFromInstance(keywords)
admin.repairFields(keywords)
layout = X.array()
layout += admin.getViewLayout(keywords)
layout += admin.getViewLayout(fields = None)
buttonsBar = X.div(_class = 'buttons-bar')
layout += buttonsBar
@ -217,34 +179,27 @@ class AdministrableWebMixin(WebMixin):
layout,_('%s Settings') % _(self.objectsNameCapitalized))
admin.isPublicForWeb = 1
def adminEdit(self, again = '', error = '', **keywords):
def adminEdit(self):
if not self.isAdmin():
return accessForbidden()
admin = self.getAdmin()
return self.adminObjectEdit(admin)
adminEdit.isPublicForWeb = 1
def adminObjectEdit(self, admin):
context.push(_level = 'adminEdit',
defaultDispatcherId = context.getVar('dispatcherId'),
layoutMode = 'edit')
try:
if keywords is None:
keywords = {}
if not self.isAdmin():
return accessForbidden()
admin = self.getAdmin()
if keywords.has_key('adminObject') and \
isinstance(keywords['adminObject'], admin.__class__):
admin = keywords['adminObject']
del keywords['adminObject']
if not again:
admin.makeFieldsFromInstance(keywords)
admin.repairFields(keywords)
layout = X.array()
if error:
layout += admin.getErrorLayout(keywords)
if context.getVar('error'):
layout += admin.getErrorLayout()
form = X.form(
action = X.actionUrl('adminSubmit'),
enctype= 'multipart/form-data', method = 'post')
layout += form
form += admin.getEditLayout(keywords)
form += admin.getEditLayout(fields = None)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
@ -255,7 +210,6 @@ class AdministrableWebMixin(WebMixin):
context.pull(_level = 'adminEdit')
return writePageLayout(layout, _('Editing %s Settings') \
% _(self.objectsNameCapitalized))
adminEdit.isPublicForWeb = 1
def adminSubmit(self, **keywords):
uri = None
@ -266,25 +220,21 @@ class AdministrableWebMixin(WebMixin):
keywords = {}
if not self.isAdmin():
return accessForbidden()
admin = self.getAdmin()
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
context.setVar('again', 1)
context.setVar('hideErrors', 1)
admin = self.newAdmin(keywords)
admin.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
return self.adminEdit(adminObject = admin, **keywords)
if context.getVar('again'):
return self.adminObjectEdit(admin)
try:
self.modifyAdmin(admin)
except faults.WrongVersion:
keywords['again'] = '1'
keywords['error'] = '1'
keywords['versionError'] = '1'
uri = X.actionUrl('adminEdit')
uri.addKeywords(keywords)
return # The redirect(uri) will be returned by the finally
# instruction.
context.setVar('again', 1)
context.setVar('error', 1)
admin.setError('version', 1)
return self.adminObjectEdit(admin)
except:
if context.getVar('debug'):
raise
@ -309,14 +259,9 @@ class ObjectsWebMixin(AdministrableWebMixin):
if not self.canCloneObject(id):
return accessForbidden()
object = self.getObject(id)
keywords = {}
object.makeFieldsFromInstance(keywords)
del keywords['id']
keywords['again'] = 1
keywords['cloned'] = 1
uri = X.actionUrl('edit')
uri.addKeywords(keywords)
return redirect(uri)
object.id = None
object.version = 0
return self.editObject(object)
clone.isPublicForWeb = 1
def confirmDelete(self, id):
@ -392,10 +337,7 @@ class ObjectsWebMixin(AdministrableWebMixin):
return OK
download.isPublicForWeb = 1
def edit(self, id = '', **keywords):
if keywords is None:
keywords = {}
keywords['id'] = id
def edit(self, id = ''):
if id and not self.hasObject(id):
return pageNotFound()
@ -407,50 +349,45 @@ class ObjectsWebMixin(AdministrableWebMixin):
else:
if not self.canAddObject():
return accessForbidden()
object = self.newObject(keywords)
object = self.newObject(None)
return self.editObject(object, **keywords)
if not object.id:
object.fillWithDefaultValues()
return self.editObject(object)
edit.isPublicForWeb = 1
def editObject(self, object, again = 0, error = 0, **keywords):
if object.id and not again:
object.makeFieldsFromInstance(keywords)
if not object.id and not again:
object.initFields(keywords)
object.repairFields(keywords)
def editObject(self, object):
if not object.id:
headerTitle = _(self.newObjectNameCapitalized)
else:
headerTitle = _('Editing %s - %s') % (
_(self.objectNameCapitalized), object.getLabel())
if keywords.has_key('headerTitle'):
headerTitle = keywords['headerTitle']
if context.getVar('headerTitle'):
headerTitle = context.getVar('headerTitle')
context.push(_level = 'edit',
isCreateEditMode = not object.id,
layoutMode = 'edit')
try:
layout = X.array()
leadIn = self.getEditLeadIn(object, keywords)
leadIn = self.getEditLeadIn(object)
if leadIn:
layout += X.enclose(leadIn, _class = 'lead-in')
if error:
layout += object.getErrorLayout(keywords)
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(action = X.actionUrl('submit'),
enctype = 'multipart/form-data', method = 'post')
layout += form
if keywords.has_key('cloned') and keywords['cloned']:
form += X.input(name = 'cloned', type = 'hidden', value = '1')
if keywords.has_key('nextUri') and keywords['nextUri']:
if context.getVar('nextUri'):
form += X.input(name = 'nextUri', type = 'hidden',
value = keywords['nextUri'])
value = context.getVar('nextUri'))
slot = slots.Root(object)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, keywords)
form += widget.getModelPageBodyLayout(slot, fields = None)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
@ -471,7 +408,7 @@ class ObjectsWebMixin(AdministrableWebMixin):
finally:
context.pull(_level = 'edit')
def getEditLeadIn(self, object, fields):
def getEditLeadIn(self, object):
return None
def getObjectsLayout(self, partialObjects, objectIds,
@ -526,11 +463,6 @@ class ObjectsWebMixin(AdministrableWebMixin):
if kind.hasToMakeFieldFromValue:
kind.makeFieldFromValue(
slot, fields, slot.getValue())
for slotName in slotNames:
slot = partialObject.getSlot(slotName)
kind = slot.getKind()
if kind.hasToRepairField:
kind.repairField(slot, fields)
tr = X.tr(_class = ((even and 'even') or 'odd'))
even = not even
tbody += tr
@ -549,7 +481,6 @@ class ObjectsWebMixin(AdministrableWebMixin):
ul += X.li()(
X.a(href = X.idUrl(partialObject.id))(label))
#layout += X.br()
return layout
def getObjectsSectionLayout(self, partialObjects, intertitle,
@ -592,18 +523,6 @@ class ObjectsWebMixin(AdministrableWebMixin):
else:
label = partialObject.getLabel()
fields = {}
if slotNames:
for slotName in slotNames:
slot = partialObject.getSlot(slotName)
kind = slot.getKind()
if kind.hasToMakeFieldFromValue:
kind.makeFieldFromValue(
slot, fields, slot.getValue())
for slotName in slotNames:
slot = partialObject.getSlot(slotName)
kind = slot.getKind()
if kind.hasToRepairField:
kind.repairField(slot, fields)
tr = X.tr(_class = ((even and 'even') or 'odd'))
even = not even
tbody += tr
@ -715,7 +634,7 @@ class ObjectsWebMixin(AdministrableWebMixin):
return None
return layout
def getViewLeadIn(self, object, fields):
def getViewLeadIn(self, object):
return None
def getViewNavigationButtonsBarLayout(self, object, fields):
@ -742,10 +661,7 @@ class ObjectsWebMixin(AdministrableWebMixin):
image = download
image.isPublicForWeb = 1
def imageEdit(self, id = '', path = '', **keywords):
if keywords is None:
keywords = {}
keywords['id'] = id
def imageEdit(self, id = '', path = ''):
if id:
localId = commonTools.extractLocalId(id)
if localId == '__admin__':
@ -762,21 +678,20 @@ class ObjectsWebMixin(AdministrableWebMixin):
else:
if not self.canAddObject():
return accessForbidden()
object = self.newObject(keywords)
object = self.newObject()
uploadSlot = object.getSlotByPath(path)
upload = uploadSlot.getValue()
data = upload.getSlot('data', parentSlot = uploadSlot).getField(
keywords)
data = upload.getSlot('data', parentSlot = uploadSlot).getValue()
req = context.getVar('req')
dataFileName = upload.getSlot(
'dataFileName', parentSlot = uploadSlot).getField(keywords)
'dataFileName', parentSlot = uploadSlot).getValue()
if dataFileName:
req.headers_out['Content-disposition'] = \
'attachment; filename="%s"' % dataFileName
req.headers_out['Content-length'] = str(len(data))
req.content_type = upload.getSlot(
'dataType', parentSlot = uploadSlot).getField(keywords)
'dataType', parentSlot = uploadSlot).getValue()
setHttpCookie()
req.send_http_header()
if req.method == 'HEAD':
@ -840,8 +755,7 @@ class ObjectsWebMixin(AdministrableWebMixin):
terms = terms.split(' ')
object = self.newObject(keywords)
allSlotNames = object.getSlotNames()
for slotName in ['addToId', 'addToSlot', 'serverRole',
'thingName', 'thingCategory']:
for slotName in ['serverRole', 'thingName', 'thingCategory']:
if slotName in allSlotNames:
allSlotNames.remove(slotName)
for slotName in allSlotNames:
@ -877,38 +791,34 @@ class ObjectsWebMixin(AdministrableWebMixin):
keywords['id'] = id
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
context.setVar('again', 1)
context.setVar('hideErrors', 1)
error = 0
object = self.newObject(keywords)
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
object.submitFields(keywords)
object.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
return self.editObject(object = object, **keywords)
if context.getVar('again'):
return self.editObject(object = object)
if not id:
result = self.submitAddObject(object, **keywords)
else:
result = self.submitModifyObject(object, **keywords)
try:
if not id:
result = self.submitAddObject(object)
else:
result = self.submitModifyObject(object)
except:
if context.getVar('debug'):
raise
return accessForbidden() # TODO: return failure ?
if result:
return result
if not id and keywords.has_key('addToId') and keywords['addToId']:
keywords['id'] = object.id
self.submitAddObjectToOther(**keywords)
if keywords.has_key('nextUri') and keywords['nextUri']:
return redirect(keywords['nextUri'])
if context.getVar('nextUri'):
return redirect(context.getVar('nextUri'))
return redirect(X.idUrl(object.id))
submit.isPublicForWeb = 1
def submitAddObject(self, object, **keywords):
def submitAddObject(self, object):
try:
object.id = self.addObject(object)
except faults.UserAccessDenied:
@ -916,47 +826,14 @@ class ObjectsWebMixin(AdministrableWebMixin):
raise
return accessForbidden()
def submitAddObjectToOther(self, **keywords):
# FIXME: proper error handling
addToId = keywords['addToId']
proxy = getProxy(addToId)
objectWeAddTo = proxy.getObject(addToId)
if keywords.has_key('addToSlot') and keywords['addToSlot']:
slotName = keywords['addToSlot']
slot = objectWeAddTo.getSlot(slotName)
else:
# if not slotname specified, we take the first sequence
for slotName in objectWeAddTo.getOrderedLayoutSlotNames():
slot = objectWeAddTo.getSlot(slotName)
kind = slot.getKind()
if kind.getThingName() != 'Sequence':
continue
if kind.itemKind.getThingName() != 'Id':
continue
break
else:
raise 'Unable to find a slot to add to'
kindName = slot.getKind().getThingName()
cV = slot.getValue()
if kindName == 'Sequence':
if not cV:
cV = []
cV.append(keywords['id'])
else:
cV = keywords['id']
setattr(objectWeAddTo, slotName, cV)
proxy.modifyObject(objectWeAddTo)
def submitModifyObject(self, object, **keywords):
def submitModifyObject(self, object):
try:
self.modifyPartialObject(object, object.getSlotToModifyNames())
except faults.WrongVersion:
keywords['again'] = '1'
keywords['error'] = '1'
keywords['versionError'] = '1'
uri = X.idUrl(object.id, 'edit')
uri.addKeywords(keywords)
return redirect(uri)
context.setVar('again', 1)
context.setVar('error', 1)
object.setError('version', 1)
return self.editObject(object)
except faults.UserAccessDenied:
return accessForbidden()
@ -1032,24 +909,19 @@ class ObjectsWebMixin(AdministrableWebMixin):
object = self.getObject(id)
rememberObject(id)
keywords = {}
object.makeFieldsFromInstance(keywords)
object.repairFields(keywords)
label = object.getLabelTranslated(context.getVar('readLanguages'))
layout = X.array()
leadIn = self.getViewLeadIn(object, keywords)
leadIn = self.getViewLeadIn(object)
if leadIn:
layout += X.enclose(leadIn, _class = 'lead-in')
slot = slots.Root(object)
widget = slot.getWidget()
layout += widget.getModelPageBodyLayout(slot, keywords)
layout += widget.getModelPageBodyLayout(slot, None)
pageTitle = context.getVar('pageTitle', default = None)
layout += self.getViewAboveButtonsBarLayout(object, keywords)
layout += self.getViewButtonsBarLayout(object, keywords)
layout += self.getViewBelowButtonsBarLayout(object, keywords)
layout += self.getViewAboveButtonsBarLayout(object, None)
layout += self.getViewButtonsBarLayout(object, None)
layout += self.getViewBelowButtonsBarLayout(object, None)
context.push(
currentObject = WebAPI.GlasnostObject(object = object),
@ -1151,3 +1023,109 @@ class ObjectsWebMixin(AdministrableWebMixin):
raise apache.SERVER_RETURN, HTTP_INTERNAL_SERVER_ERROR
return OK
class CommentableObjectMixin(things.ThingMixin):
def addComment(self, id):
if not self.hasObject(id):
return pageNotFound()
webRole = getWebForServerRole('comments')
if not webRole:
return pageNotFound()
object = webRole.newObject(None)
object.fillWithDefaultValues()
return self.addCommentObject(id, object)
addComment.isPublicForWeb = 1
def addCommentObject(self, id, object):
webRole = getWebForServerRole('comments')
context.push(_level = 'edit', layoutMode = 'edit')
try:
layout = X.array()
leadIn = webRole.getEditLeadIn(object)
if leadIn:
layout += X.enclose(leadIn, _class = 'lead-in')
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(action = X.idUrl(id, 'addCommentSubmit'),
enctype = 'multipart/form-data', method = 'post')
layout += form
slot = slots.Root(object)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, None)
buttonsBar = X.div(_class = 'buttons-bar')(
X.buttonInForm('add', 'addButton'))
form += buttonsBar
return writePageLayout(layout, _(webRole.newObjectNameCapitalized))
finally:
context.pull(_level = 'edit')
def addCommentSubmit(self, id, **keywords):
if keywords is None:
keywords = {}
webRole = getWebForServerRole('comments')
object = webRole.newObject(keywords)
object.submitFields(keywords)
object.parentId = id
if context.getVar('again'):
return self.addCommentObject(id, object)
try:
webRole.submitAddObject(object)
except:
if context.getVar('debug'):
raise
return accessForbidden()
return redirect(X.idUrl(id, 'withComments'))
addCommentSubmit.isPublicForWeb = 1
def commentsLayout(self, id):
commentsWeb = getWebForServerRole('comments')
comments = commentsWeb.getObjectsWithParent(id).values()
comments.sort(lambda x,y: cmp(x.creationTime, y.creationTime))
layout = X.array()
if len(comments) == 0:
layout += X.p(_('No comment.'))
for i, comment in zip(range(len(comments)), comments):
layout += X.div(_class = 'comment', id = 'comment-%d' % (i+i))(
X.span(_class = 'comment-no')(str(i+1)),
comment.getViewLayout(self, None))
# TODO: check if we can add comments to the object
layout += X.div(_class = 'buttons-bar')(
X.buttonStandalone('add', X.idUrl(id, 'addComment')))
return layout
def comments(self, id):
layout = self.commentsLayout(id)
return writePageLayout(layout, _('Comments'))
comments.isPublicForWeb = 1
def withComments(self, id):
object = self.getObject(id)
rememberObject(id)
label = object.getLabelTranslated(context.getVar('readLanguages'))
layout = X.array()
slot = slots.Root(object)
widget = slot.getWidget()
layout += widget.getModelPageBodyLayout(slot, {})
layout += self.getViewButtonsBarLayout(object, None)
pageTitle = context.getVar('pageTitle', default = None)
layout += X.h2(id = 'comments')(_('Comments'))
context.push(sectionLevel = context.getVar('sectionLevel') + 1)
layout += self.commentsLayout(id)
context.pull()
context.push(
currentObject = WebAPI.GlasnostObject(object = object),
)
if not pageTitle:
pageTitle = '%s - %s' % (_(self.objectNameCapitalized), label)
layout = writePageLayout(layout, pageTitle)
context.pull()
return layout
withComments.isPublicForWeb = 1

View File

@ -70,21 +70,19 @@ register(PageName)
class PageNamesWeb(ObjectsWebMixin, PageNamesProxy):
def submitAddObject(self, object, **keywords):
def submitAddObject(self, object):
try:
return ObjectsWebMixin.submitAddObject(self, object, **keywords)
return ObjectsWebMixin.submitAddObject(self, object)
except faults.DuplicateValue:
keywords['again'] = '1'
keywords['error'] = '1'
context.setVar('error', 1)
object.setError('self.name', f)
return self.edit(object = object, **keywords)
return self.editObject(object)
def submitModifyObject(self, object, **keywords):
def submitModifyObject(self, object):
try:
return ObjectsWebMixin.submitModifyObject(self, object, **keywords)
return ObjectsWebMixin.submitModifyObject(self, object)
except faults.DuplicateValue:
keywords['again'] = '1'
keywords['error'] = '1'
context.setVar('error', 1)
object.setError('self.name', f)
return self.edit(object = object, **keywords)
return self.editObject(object)

View File

@ -70,7 +70,7 @@ class Person(ObjectWebMixin, Person):
email_kind_widgetName = 'Email' #'InputText'
fingerprint_kind_widget_fieldLabel = N_('GnuPG Fingerprint')
fingerprint_kind_widget_size = 40
fingerprint_kind_widget_size = 60
fingerprint_kind_widgetName = 'InputText'
firstName_kind_widget_fieldLabel = N_('First Name')
@ -96,6 +96,8 @@ class Person(ObjectWebMixin, Person):
voteTokens_kind_stateInViewMode = 'hidden'
def getEditLayout(self, fields, parentSlot = None):
if context.getVar('userId') != self.id:
return ObjectWebMixin.getEditLayout(self, fields, parentSlot)
dict = { 'firstName': _('Enter your first name.'),
'lastName': _('Enter your last name.'),
'nickname': _('Enter your nickname (optional).'),
@ -104,7 +106,7 @@ class Person(ObjectWebMixin, Person):
'(mandatory to receive encrypted emails).'),
}
for k, v in dict.items():
kind = copy.copy(getattr(self, '%s_kind' % k))
kind = copy.copy(self.getSlot(k).getKind())
kind.balloonHelp = v
setattr(self, '%s_kind' % k, kind)
layout = ObjectWebMixin.getEditLayout(self, fields, parentSlot)
@ -150,16 +152,6 @@ register(Person)
class PeopleWeb(ObjectsWebMixin, PeopleProxy):
def edit(self, id = '', **keywords):
userToken = context.getVar('userToken')
if not userToken:
if keywords is None:
keywords = {}
keywords['headerTitle'] = _('New Account')
return ObjectsWebMixin.edit(self, id, **keywords)
edit.isPublicForWeb = 1
def getSortedIds(self, objects):
labels = {}
for object in objects.values():
@ -187,9 +179,10 @@ class PeopleWeb(ObjectsWebMixin, PeopleProxy):
for election in elections:
if not person.id in election.getVoterIds():
continue
tr = X.tr(X.td(X.a(href = X.idUrl(election.id))(
election.getLabelTranslated(
context.getVar('readLanguages')))))
tr = X.tr(X.th(scope = 'row')(
X.a(href = X.idUrl(election.id))(
election.getLabelTranslated(
context.getVar('readLanguages')))))
table += tr
if not votes.has_key(election.id):
tr += X.td(_('Abstention'))
@ -228,80 +221,46 @@ class PeopleWeb(ObjectsWebMixin, PeopleProxy):
_("""The votes for the closed elections"""))
return layout
def submit(self, id = '', **keywords):
if keywords is None:
keywords = {}
keywords['id'] = id
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
def submitAddObject(self, object):
error = 0
object = self.newObject(keywords)
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
object.submitFields(keywords)
try:
return ObjectsWebMixin.submitAddObject(self, object)
except faults.DuplicateFullName, f:
error = 1
object.setError('self.lastName', f)
except faults.DuplicateEmail, f:
error = 1
object.setError('self.email', f)
except faults.DuplicateFingerprint:
error = 1
object.setError('self.fingerprint', f)
if keywords.has_key('again') and keywords['again']:
return self.edit(object = object, **keywords)
if not id:
try:
id = self.addObject(object)
except faults.DuplicateFullName, f:
error = 1
object.getSlot('lastName').error = f
except faults.DuplicateEmail, f:
error = 1
object.getSlot('email').error = f
except faults.DuplicateFingerprint:
error = 1
object.getSlot('fingerprint').error = f
except:
if context.getVar('debug'):
raise
return accessForbidden()
else:
error = 0
if error:
keywords['again'] = '1'
keywords['error'] = '1'
uri = X.idUrl(id, 'edit')
return self.edit(object = object, **keywords)
### if object.email:
### return success(
### _("""\
### The account has successfully been created.
### An email containing the password has been sent to %s.\
### """) % object.email, X.idUrl(id))
else:
try:
self.modifyPartialObject(object, object.getSlotToModifyNames())
except faults.WrongVersion:
error = 1
keywords['versionError'] = '1'
except faults.DuplicateFullName, f:
error = 1
object.getSlot('lastName').error = f
except faults.DuplicateEmail, f:
error = 1
object.getSlot('email').error = f
except faults.DuplicateFingerprint, f:
error = 1
object.getSlot('fingerprint').error = f
except:
if context.getVar('debug'):
raise
return accessForbidden()
else:
error = 0
if error:
keywords['again'] = '1'
keywords['error'] = '1'
uri = X.idUrl(id, 'edit')
return self.edit(object = object, **keywords)
return redirect(X.idUrl(id))
submit.isPublicForWeb = 1
if error:
context.setVar('again', 1)
context.setVar('error', 1)
return self.editObject(object)
def submitModifyObject(self, object):
error = 0
try:
self.modifyPartialObject(object, object.getSlotToModifyNames())
except faults.WrongVersion:
error = 1
object.setError('version', 1)
except faults.DuplicateFullName, f:
error = 1
object.setError('self.lastName', f)
except faults.DuplicateEmail, f:
error = 1
object.setError('self.email', f)
except faults.DuplicateFingerprint, f:
error = 1
object.setError('self.fingerprint', f)
if error:
context.setVar('again', 1)
context.setVar('error', 1)
return self.editObject(object)
def view(self, id):
webTools.addContextualHeader('noindex')

View File

@ -96,32 +96,31 @@ register(Preference)
class PreferencesWeb(WebMixin, PreferencesProxy):
def edit(self, again = '', error = '', **keywords):
if keywords is None:
keywords = {}
def edit(self):
userToken = context.getVar('userToken', default = '')
if not userToken:
return accessForbidden()
preference = self.getPreference()
if not again:
preference.makeFieldsFromInstance(keywords)
preference.repairFields(keywords)
return self.editObject(preference)
edit.isPublicForWeb = 1
def editObject(self, preference):
headerTitle = _('Editing Preferences')
context.push(_level = 'edit', layoutMode = 'edit')
try:
layout = X.array()
if error:
layout += preference.getErrorLayout(keywords)
if context.getVar('error'):
layout += preference.getErrorLayout()
form = X.form(action = X.actionUrl('submit'),
enctype= 'multipart/form-data', method = 'post')
layout += form
slot = slots.Root(preference)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, keywords)
form += widget.getModelPageBodyLayout(slot, None)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
@ -132,34 +131,24 @@ class PreferencesWeb(WebMixin, PreferencesProxy):
return writePageLayout(layout, headerTitle)
finally:
context.pull(_level = 'edit')
edit.isPublicForWeb = 1
def submit(self, **keywords):
if keywords is None:
keywords = {}
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
error = 0
context.setVar('again', 1)
context.setVar('hideErrors', 1)
preference = Preference()
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
preference.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
uri = X.actionUrl('edit')
uri.addKeywords(keywords)
return redirect(uri)
preference.submitFields(keywords)
if context.getVar('again'):
return self.editObject(preference)
try:
self.setPreference(preference)
except faults.WrongVersion:
keywords['again'] = '1'
keywords['error'] = '1'
keywords['versionError'] = '1'
uri = X.actionUrl('edit')
uri.addKeywords(keywords)
return redirect(uri)
context.setVar('again', 1)
context.setVar('error', 1)
preference.setError('version', 1)
return self.editObject(preference)
except:
if context.getVar('debug'):
raise
@ -174,14 +163,10 @@ class PreferencesWeb(WebMixin, PreferencesProxy):
preference = self.getPreference()
keywords = {}
preference.makeFieldsFromInstance(keywords)
preference.repairFields(keywords)
layout = X.array()
slot = slots.Root(preference)
widget = slot.getWidget()
layout += widget.getModelPageBodyLayout(slot, keywords)
layout += widget.getModelPageBodyLayout(slot)
buttonsBar = X.div(_class = 'buttons-bar')
layout += buttonsBar

View File

@ -78,11 +78,10 @@ class Rubric(ObjectWebMixin, Rubric):
def getViewLayout(self, fields, parentSlot = None):
layout = X.array()
contentId = fields['contentId']
if contentId:
web = getWeb(contentId)
if web.canGetObject(contentId):
object = web.getObject(contentId)
if self.contentId:
web = getWeb(self.contentId)
if web.canGetObject(self.contentId):
object = web.getObject(self.contentId)
if object.getLabel() == self.getLabel() and \
parentSlot and parentSlot.getLabel() == 'Root':
context.setVar('pageTitle',
@ -92,9 +91,9 @@ class Rubric(ObjectWebMixin, Rubric):
layout += object.getEmbeddedViewLayout()
if web.canModifyObject(contentId):
if web.canModifyObject(self.contentId):
layout += X.buttonStandalone(
'edit', X.idUrl(contentId, 'edit'))
'edit', X.idUrl(self.contentId, 'edit'))
layout += X.div(_class = 'clear')(X.hr())
@ -141,12 +140,80 @@ class RubricsWeb(ObjectsWebMixin, RubricsProxy):
if not hasattr(webRole, 'canAddObject') or \
not webRole.canAddObject():
continue
select += X.option(value = role.urlNew.add(
'addToId', object.id).add(
'nextUri', X.idUrl(object.id).getAsAbsoluteUrl()).add(
'addToSlot', 'membersSet'))(
select += X.option(
value = X.idUrl(object.id,
'addContent/%s' % role.web.serverRole))(
_(webRole.objectNameCapitalized))
if select.children:
layout += form
return layout
def addContent(self, id, serverRole):
if not self.hasObject(id):
return pageNotFound()
rubric = self.getObject(id)
webRole = getWebForServerRole(serverRole)
if webRole is None:
return pageNotFound()
object = webRole.newObject(None)
object.fillWithDefaultValues()
if object.hasSlotName('writersSet'):
object.writersSet = rubric.writersSet
if object.hasSlotName('readersSet'):
object.readersSet = rubric.readersSet
return self.addContentObject(id, serverRole, object)
addContent.isPublicForWeb = 1
def addContentObject(self, id, serverRole, object):
webRole = getWebForServerRole(serverRole)
context.push(_level = 'edit', layoutMode = 'edit')
try:
layout = X.array()
leadIn = webRole.getEditLeadIn(object)
if leadIn:
layout += X.enclose(leadIn, _class = 'lead-in')
if context.getVar('error'):
layout += object.getErrorLayout()
form = X.form(action = X.idUrl(id, 'addContentSubmit/%s' % serverRole),
enctype = 'multipart/form-data', method = 'post')
layout += form
slot = slots.Root(object)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, None)
buttonsBar = X.div(_class = 'buttons-bar')(
X.buttonInForm('create', 'createButton'))
form += buttonsBar
return writePageLayout(layout,
_('Add %s To Rubric') % webRole.objectNameCapitalized)
finally:
context.pull(_level = 'edit')
def addContentSubmit(self, id, serverRole, **keywords):
if keywords is None:
keywords = {}
webRole = getWebForServerRole(serverRole)
object = webRole.newObject(keywords)
object.submitFields(keywords)
if context.getVar('again'):
return self.addContentObject(id, serverRole, object)
try:
webRole.submitAddObject(object)
except:
if context.getVar('debug'):
raise
return accessForbidden()
rubric = self.getObject(id)
if not rubric.membersSet:
rubric.membersSet = []
rubric.membersSet.append(object.id)
self.modifyObject(rubric)
return redirect(X.idUrl(id))
addContentSubmit.isPublicForWeb = 1

View File

@ -68,11 +68,11 @@ class SimilarStringWidget(widgets.TextArea):
def getHtmlValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
similarString = slot.getField(fields, default = '')
similarString = slot.getValue() or ''
assert self.isInForm()
assert self.isReadOnly(slot)
sourceStringSlot = slot.getContainer().getSlot('sourceString')
sourceString = sourceStringSlot.getField(fields, default = '')
sourceString = sourceStringSlot.getValue() or ''
layout = X.array(
self.getModelHiddenLayout(slot, fields),
@ -99,63 +99,63 @@ class SimilarStringWidget(widgets.TextArea):
return layout
widgets.register(SimilarStringWidget)
class TranslationToAddWidget(widgets.BaseWidget):
thingName = 'TranslationToAdd'
def getHtmlValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = slot.getField(fields, default = '')
if not self.isInForm():
return
fromFieldName = slot.getFieldOptionName('from')
toFieldName = slot.getFieldOptionName('to')
fromFieldValue = slot.getFieldOption(fields, 'from', default = '')
toFieldValue = slot.getFieldOption(fields, 'to', default = '')
assert self.isInForm()
assert not self.isReadOnly(slot)
values = translation.languageKeys
labels = translation.languageLabels
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
layout += self.getModelHelpLayout(slot, fields)
fromSelect = X.select(name = fromFieldName)
if not fromFieldValue in values:
fromSelect += X.option(
selected = 'selected', value = '')(_('None'))
for value in values:
optionAttributes = {}
if value == fromFieldValue:
optionAttributes['selected'] = 'selected'
fromSelect += X.option(value = value, **optionAttributes)(
_(labels[value]))
toSelect = X.select(name = toFieldName)
if not toFieldValue in values:
toSelect += X.option(
selected = 'selected', value = '')(_('None'))
for value in values:
optionAttributes = {}
if value == toFieldValue:
optionAttributes['selected'] = 'selected'
toSelect += X.option(value = value, **optionAttributes)(
_(labels[value]))
layout += _('From ')
layout += fromSelect
layout += _(' to ')
layout += toSelect
layout += ' '
layout += X.array( _('From '), fromSelect, _(' to '), toSelect, ' ')
layout += X.buttonInForm('add', slot.getFieldOptionName('addButton'))
return layout
def submit(self, slot, fields):
addButtonName = slot.getFieldOptionName('addButton')
if not isButtonSelected(addButtonName, fields):
return None
fromLanguage = slot.getFieldOption(fields, 'from') or ''
toLanguage = slot.getFieldOption(fields, 'to') or ''
if len(fromLanguage) != 2 or len(toLanguage) != 2:
return None
object = slot.getObject()
object.translationLanguages.append('%s%s' % (fromLanguage, toLanguage))
slotKey = 'translatorsSet_%s_%s' % (fromLanguage, toLanguage)
setattr(object, slotKey, None)
kind = commonTools.newThing('kind', 'UsersSet')
kind.widget = TranslatorsSetWidget()
kind.buildKinds()
setattr(object, slotKey + '_kind', kind)
context.setVar('again', 1)
context.setVar('hideErrors', 1)
return None
widgets.register(TranslationToAddWidget)
class TranslatorsSetWidget(widgets.Multi):
thingName = 'TranslatorsSet'
def getHtmlFieldLabel(self, slot):
fieldName = slot.getFieldName()
assert fieldName.endswith('TranslatorsSet')
languages = fieldName[:-len('TranslatorsSet')][-4:]
fromLanguage = languages[:2]
toLanguage = languages[2:4]
fromLanguage = fieldName[-5:-3]
toLanguage = fieldName[-2:]
fieldLabelLocalized = _('%(from)s to %(to)s Translators') % {
'from': _(translation.languageLabels[fromLanguage]),
'to': _(translation.languageLabels[toLanguage]),
@ -167,184 +167,31 @@ widgets.register(TranslatorsSetWidget)
class AdminTranslations(AdminWithoutWritersMixin, AdminTranslations):
translationLanguages = None
translationToAdd = None
translationToAdd_kindName = 'TranslationToAdd'
translationToAdd_kind_widget_fieldLabel = N_('Translation')
translationToAdd_kind_widgetName = 'TranslationToAdd'
translatorsSets_kind_importExport = 'private'
translatorsSets_kind_stateInEditMode = 'hidden'
translatorsSets_kind_stateInViewMode = 'hidden'
translatorsSets_kind_isRequired = 0
translatorsSets_widgetName = 'TranslatorsSetsWidget'
def addTranslatorsSetsFields(self, localizationKeys):
for localizationKey in localizationKeys:
attributeName = localizationKey + 'TranslatorsSet'
if not hasattr(self, attributeName):
setattr(self, attributeName, None)
setattr(self, attributeName + '_kind', kinds.Sequence(
itemKind = kinds.Id(
serverRoles = ['groups', 'people'],
widget = widgets.SelectId()),
widget = TranslatorsSetWidget()))
def delTranslatorsSetsFields(self, localizationKeys):
for localizationKey in localizationKeys:
attributeName = localizationKey + 'TranslatorsSet'
delattr(self, attributeName + '_kind')
def exportToXmlRpc(self, requiredSlotNames = None, parentSlot = None):
# It would have been better not having been forced to write this
# here... Something like a better field_exporter support...
result = AdminWithoutWritersCommon.exportToXmlRpc(
self, requiredSlotNames = requiredSlotNames,
parentSlot = parentSlot)
translatorsSets = {}
for translatorsLabel, translatorsSet in self.__dict__.items():
if not translatorsLabel.endswith('TranslatorsSet'):
continue
if translatorsSet is None:
continue
localizationKey = translatorsLabel[:-len('TranslatorsSet')][-4:]
translatorsSets[localizationKey] = translatorsSet
if translatorsSets:
result['translatorsSets'] = translatorsSets
else:
if not result.has_key('__noneSlotNames__'):
result['__noneSlotNames__'] = []
result['__noneSlotNames__'].append('translatorsSets')
return result
def getEditLayout(self, fields, parentSlot = None):
localizationKeys = []
for translatorsLabel in fields.keys():
if not translatorsLabel.endswith('TranslatorsSet_count'):
continue
localizationKey = translatorsLabel[:-len('TranslatorsSet_count')][
-4:]
localizationKeys.append(localizationKey)
self.addTranslatorsSetsFields(localizationKeys)
context.push(fields = fields)
layout = AdminWithoutWritersMixin.getEditLayout(
self, fields, parentSlot = parentSlot)
context.pull()
self.delTranslatorsSetsFields(localizationKeys)
return layout
def getOrderedLayoutSlotNames(self, parentSlot = None):
slotNames = AdminWithoutWritersCommon.getOrderedLayoutSlotNames(
self, parentSlot = parentSlot)
slotNames = slotNames[:]
fields = context.getVar('fields')
for translatorsLabel in fields.keys():
if not translatorsLabel.endswith('TranslatorsSet_count'):
continue
localizationKey = translatorsLabel[:-len('TranslatorsSet_count')][
-4:]
slotNames.append(localizationKey + 'TranslatorsSet')
slotNames += ['translationToAdd']
def getLayoutSlotNames(self, fields, parentSlot = None):
slotNames = AdminWithoutWritersMixin.getLayoutSlotNames(self, fields, parentSlot)
slotNames.remove('translatorsSets')
slotNames.remove('translationToAdd')
return slotNames
def getViewLayout(self, fields, parentSlot = None):
localizationKeys = []
for translatorsLabel in fields.keys():
if not translatorsLabel.endswith('TranslatorsSet_count'):
continue
localizationKey = translatorsLabel[:-len('TranslatorsSet_count')][
-4:]
localizationKeys.append(localizationKey)
self.addTranslatorsSetsFields(localizationKeys)
context.push(fields = fields)
layout = AdminWithoutWritersMixin.getViewLayout(
self, fields, parentSlot = parentSlot)
context.pull()
self.delTranslatorsSetsFields(localizationKeys)
return layout
def getViewLayoutSlotNames(self, fields, parentSlot = None):
slotNames = AdminWithoutWritersMixin.getViewLayoutSlotNames(
self, fields, parentSlot = parentSlot)
slotNames = slotNames[:]
if 'translationToAdd' in slotNames:
slotNames.remove('translationToAdd')
def getEditLayoutSlotNames(self, fields, parentSlot = None):
slotNames = AdminWithoutWritersMixin.getViewLayoutSlotNames(self,
fields, parentSlot)
slotNames.append('translationToAdd')
return slotNames
def importFromXmlRpc(self, dataImport, parentSlot = None):
if dataImport.has_key('__noneSlotNames__'):
noneSlotNames = dataImport['__noneSlotNames__']
else:
noneSlotNames = []
for slotName in self.getSlotNames(parentSlot = parentSlot):
if slotName in [
'__noneSlotNames__', '__thingCategory__', '__thingName__']:
continue
# A slotName must always be a valid Python Indentifier, so no
# encoding is needed to for the dataImport keys.
if dataImport.has_key(slotName):
exportedValue = dataImport[slotName]
elif slotName in noneSlotNames:
exportedValue = None
else:
continue
if slotName == 'translatorsSets':
if exportedValue is None:
continue
for localizationKey, translatorsSet in exportedValue.items():
slotName = localizationKey + 'TranslatorsSet'
setattr(self, slotName, translatorsSet)
continue
slot = self.getSlot(slotName)
kind = slot.getKind()
if not kind.isImportable():
continue
slot.setValue(kind.importValueFromXmlRpc(slot, exportedValue))
def makeFieldsFromInstance(self, fields, parentSlot = None):
localizationKeys = []
for translatorsLabel in self.__dict__.keys():
if not translatorsLabel.endswith('TranslatorsSet'):
continue
localizationKey = translatorsLabel[:-len('TranslatorsSet')][-4:]
localizationKeys.append(localizationKey)
self.addTranslatorsSetsFields(localizationKeys)
AdminWithoutWritersMixin.makeFieldsFromInstance(
self, fields, parentSlot = parentSlot)
self.delTranslatorsSetsFields(localizationKeys)
def repairFields(self, fields, parentSlot = None):
localizationKeys = []
for translatorsLabel in fields.keys():
if not translatorsLabel.endswith('TranslatorsSet_count'):
continue
localizationKey = translatorsLabel[:-len('TranslatorsSet_count')][
-4:]
localizationKeys.append(localizationKey)
self.addTranslatorsSetsFields(localizationKeys)
AdminWithoutWritersMixin.repairFields(
self, fields, parentSlot = parentSlot)
self.delTranslatorsSetsFields(localizationKeys)
def submitFields(self, fields, parentSlot = None):
localizationKeys = []
for translatorsLabel in fields.keys():
if not translatorsLabel.endswith('TranslatorsSet_count'):
continue
localizationKey = translatorsLabel[:-len('TranslatorsSet_count')][
-4:]
localizationKeys.append(localizationKey)
self.addTranslatorsSetsFields(localizationKeys)
AdminWithoutWritersMixin.submitFields(
self, fields, parentSlot = parentSlot)
self.delTranslatorsSetsFields(localizationKeys)
register(AdminTranslations)
class Localization(ObjectWebMixin, Localization):
destinationLanguage_kind_defaultValue = 'VoteRanking'
destinationLanguage_kind_defaultValue = 'VoteRanking' # FIXME: wtf???
destinationLanguage_kind_stateInEditMode = 'hidden'
destinationLanguage_kind_stateInViewMode = 'hidden'
destinationLanguage_kind_widget_fieldLabel = N_('Translation Language')
@ -408,9 +255,8 @@ class Localization(ObjectWebMixin, Localization):
layout = X.array()
nbLines = len([
x
for x in self.getSlot(
'sourceString', parentSlot = parentSlot).getField(
fields, default = '')
for x in (self.getSlot(
'sourceString', parentSlot = parentSlot).getValue() or '')
if x == '\n'])
if nbLines > 18:
nbLinesDestination = 20
@ -430,8 +276,7 @@ class Localization(ObjectWebMixin, Localization):
hiddenSlotNames = ObjectWebMixin.getEditLayoutHiddenSlotNames(
self, fields, parentSlot = parentSlot)
hiddenSlotNames = hiddenSlotNames[:]
if self.getSlot('isTranslatable', parentSlot = parentSlot).getField(
fields):
if self.getSlot('isTranslatable', parentSlot = parentSlot).getValue():
isTranslatable = 1
else:
isTranslatable = 0
@ -445,14 +290,13 @@ class Localization(ObjectWebMixin, Localization):
slotNames = ObjectWebMixin.getEditLayoutSlotNames(
self, fields, parentSlot = parentSlot)
slotNames = slotNames[:]
if self.getSlot('isTranslatable', parentSlot = parentSlot).getField(
fields):
if self.getSlot('isTranslatable', parentSlot = parentSlot).getValue():
isTranslatable = 1
else:
isTranslatable = 0
slotName = 'similarString'
slot = self.getSlot(slotName, parentSlot = parentSlot)
if not isTranslatable or not slot.getField(fields):
if not isTranslatable or not slot.getValue():
if slotName in slotNames:
slotNames.remove(slotName)
return slotNames
@ -467,33 +311,16 @@ class Localization(ObjectWebMixin, Localization):
return slotNames
def submitFields(self, fields, parentSlot = None):
slot = self.getSlot('isTranslatable', parentSlot = parentSlot)
if slot.getField(fields):
isTranslatable = 1
else:
isTranslatable = 0
if fields.has_key('destinationString') and fields['destinationString']:
fields['again'] = '1'
fields['error'] = '1'
errorFields = {}
slot.setFieldOption(errorFields, 'error',
_('Destination string set while translation '\
'was marked as not necessary'))
fields.update(errorFields)
isTranslatable = 1
fields['isTranslatable'] = '1'
for slotName in ('similarString', 'destinationString', 'isFuzzy'):
# Duplicate each kind.
slot = self.getSlot(slotName, parentSlot = parentSlot)
kindName = slotName + '_kind'
setattr(self, kindName, copy.copy(getattr(self, kindName)))
getattr(self, kindName).hasToSubmitField = isTranslatable
ObjectWebMixin.submitFields(self, fields, parentSlot = parentSlot)
for slotName in ('similarString', 'destinationString', 'isFuzzy'):
# Remove kind duplicate.
kindName = slotName + '_kind'
delattr(self, kindName)
if not self.isTranslatable and self.destinationString:
context.setVar('again', 1)
context.setVar('error', 1)
slot = self.getSlot('isTranslatable')
# TODO: fault with correct description
_('Destination string set while translation '\
'was marked as not necessary')
self.setError(slot.getPath(), faults.BadValue())
self.isTranslatable = 1
register(Localization)
@ -519,26 +346,17 @@ class TranslationsWeb(ObjectsWebMixin, TranslationsProxy):
return redirect(X.actionUrl('viewAll/%s' % localizationKey))
delete.isPublicForWeb = 1
def edit(self, localizationKey, sourceStringDigest, again = '',
error = '', **keywords):
if keywords is None:
keywords = {}
keywords['localizationKey'] = localizationKey
keywords['sourceStringDigest'] = sourceStringDigest
def edit(self, localizationKey, sourceStringDigest):
if not self.hasSourceString(localizationKey, sourceStringDigest):
return pageNotFound()
if not self.canModifyLocalization(localizationKey, sourceStringDigest):
return accessForbidden()
localization = self.getLocalization(localizationKey,
sourceStringDigest)
if keywords.has_key('localization'):
if isinstance(keywords['localization'], localization.__class__):
localization = keywords['localization']
if not again:
localization.makeFieldsFromInstance(keywords)
localization.repairFields(keywords)
return self.editObject(localization, localizationKey, sourceStringDigest)
edit.isPublicForWeb = 1
def editObject(self, localization, localizationKey, sourceStringDigest):
headerTitle = _('Editing Translation')
headerTitle += ' (%s -> %s)' % (
_(translation.languageLabels[localization.sourceLanguage]),
@ -548,21 +366,19 @@ class TranslationsWeb(ObjectsWebMixin, TranslationsProxy):
context.push(_level = 'edit', layoutMode = 'edit')
try:
layout = X.array()
if error:
layout += localization.getErrorLayout(keywords)
if context.getVar('error'):
layout += localization.getErrorLayout()
form = X.form(action = X.actionUrl('submit'),
enctype= 'multipart/form-data', method = 'post')
layout += form
if keywords.has_key('cloned') and keywords['cloned']:
form += X.input(name = 'cloned', type = 'hidden', value = '1')
if keywords.has_key('nextUri') and keywords['nextUri']:
if context.getVar('nextUri'):
form += X.input(name = 'nextUri', type = 'hidden',
value = keywords['nextUri'])
value = context.getVar('nextUri'))
slot = slots.Root(localization)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, keywords)
form += widget.getModelPageBodyLayout(slot, None)
form += X.input(name = 'localizationKey', type = 'hidden',
value = localizationKey)
@ -577,12 +393,55 @@ class TranslationsWeb(ObjectsWebMixin, TranslationsProxy):
return writePageLayout(layout, headerTitle)
finally:
context.pull(_level = 'edit')
edit.isPublicForWeb = 1
def getAdmin(self, serverId = None):
admin = TranslationsProxy.getAdmin(self, serverId = serverId)
admin.translationLanguages = []
if admin.translatorsSets:
for languages, translators in admin.translatorsSets.items():
admin.translationLanguages.append(languages)
fromLanguage = languages[:2]
toLanguage = languages[2:4]
slotKey = 'translatorsSet_%s_%s' % (fromLanguage, toLanguage)
setattr(admin, slotKey, translators)
kind = commonTools.newThing('kind', 'UsersSet')
kind.widget = TranslatorsSetWidget()
kind.buildKinds()
setattr(admin, slotKey + '_kind', kind)
return admin
def modifyAdmin(self, admin, serverId = None):
admin.translatorsSets = {}
for languages in admin.translationLanguages or []:
fromLanguage = languages[:2]
toLanguage = languages[2:4]
slotKey = 'translatorsSet_%s_%s' % (fromLanguage, toLanguage)
admin.translatorsSets[languages] = admin.getSlot(slotKey).getValue()
if not admin.translatorsSets[languages]:
del admin.translatorsSets[languages]
return TranslationsProxy.modifyAdmin(self, admin, serverId = serverId)
def newAdmin(self, keywords):
ks = [x[15:20] for x in keywords.keys() if
x.startswith('translatorsSet_') and len(x) == 22]
admin = AdminTranslations()
admin.translationLanguages = []
for k in ks:
fromLanguage = k[:2]
toLanguage = k[3:5]
admin.translationLanguages.append('%s%s' % (fromLanguage, toLanguage))
slotKey = 'translatorsSet_%s_%s' % (fromLanguage, toLanguage)
setattr(admin, slotKey, None)
kind = commonTools.newThing('kind', 'UsersSet')
kind.widget = TranslatorsSetWidget()
kind.buildKinds()
setattr(admin, slotKey + '_kind', kind)
return admin
def getObjectsSectionLayout(self, key, digestsAndLabels, intertitle):
layout = None
if len(digestsAndLabels) > 0:
layout = X.array( X.h3()(intertitle) )
layout = X.array( X.h2()(intertitle) )
ul = X.ul()
layout += ul
for digest, label, wordsCount in digestsAndLabels:
@ -599,8 +458,6 @@ class TranslationsWeb(ObjectsWebMixin, TranslationsProxy):
def submit(self, localizationKey, sourceStringDigest, **keywords):
if keywords is None:
keywords = {}
keywords['localizationKey'] = localizationKey
keywords['sourceStringDigest'] = sourceStringDigest
if isButtonSelected('deleteButton', keywords):
return confirmDelete(
X.actionUrl('delete').add(
@ -608,32 +465,27 @@ class TranslationsWeb(ObjectsWebMixin, TranslationsProxy):
'sourceStringDigest', sourceStringDigest),
objectName = self.objectName)
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
error = 0
context.setVar('again', 1)
context.setVar('hideErrors', 1)
localization = Localization()
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
localization.submitFields(keywords)
if keywords.has_key('again') and keywords['again']:
return self.edit(localization = localization, **keywords)
localization.submitFields(keywords)
localization.sourceStringDigest = sourceStringDigest
if context.getVar('again'):
return self.editObject(localization, localizationKey,
sourceStringDigest)
try:
self.modifyLocalization(localization)
except faults.WrongVersion:
keywords['again'] = '1'
keywords['error'] = '1'
keywords['versionError'] = '1'
uri = X.actionUrl('edit')
uri.addKeywords(keywords)
return redirect(uri)
context.setVar('error', 1)
localization.setError('version', 1)
return self.editObject(localization, localizationKey,
sourceStringDigest)
except:
if context.getVar('debug'):
raise
return accessForbidden()
if keywords.has_key('nextUri') and keywords['nextUri']:
return redirect(keywords['nextUri'])
if context.getVar('nextUri'):
return redirect(context.getVar('nextUri'))
return redirect(X.actionUrl('viewAll/%s' % localizationKey))
submit.isPublicForWeb = 1

View File

@ -136,7 +136,8 @@ class UploadFile(ObjectWebMixin, UploadFile):
slotNames = ObjectWebMixin.getViewLayoutSlotNames(
self, fields, parentSlot = parentSlot)
slotNames = slotNames[:]
if not isTypeOfMimeType(fields['dataType'], 'image'):
dataType = self.getSlot('dataType').getValue()
if not isTypeOfMimeType(dataType, 'image'):
if 'height' in slotNames:
slotNames.remove('height')
if 'width' in slotNames:
@ -162,16 +163,13 @@ class UploadFile(ObjectWebMixin, UploadFile):
if self.dataFileName:
del self.data_kind
return layout
def makeFieldsFromInstance(self, fields, parentSlot = None):
for slotName in ('height', 'width'):
self.getSlot(slotName, parentSlot = parentSlot).getKind(
).hasToMakeFieldFromValue = self.isType('image')
ObjectWebMixin.makeFieldsFromInstance(
self, fields, parentSlot = parentSlot)
for slotName in ('height', 'width'):
del self.getSlot(slotName, parentSlot = parentSlot).getKind(
).hasToMakeFieldFromValue
def submitFields(self, fields, parentSlot = None):
ObjectWebMixin.submitFields(self, fields, parentSlot = parentSlot)
upload = context.getVar('UploadFilesXXX')
if upload:
self.dataFileName = upload.dataFileName
self.dataType = upload.dataType
register(UploadFile)
@ -180,74 +178,9 @@ class UploadFilesWeb(ObjectsWebMixin, UploadFilesProxy):
return ObjectsWebMixin.viewAll(self)
all.isPublicForWeb = 1
def editObject(self, object, again = 0, error = 0, **keywords):
if object.id and not again:
object.makeFieldsFromInstance(keywords)
if not object.id and not again:
object.initFields(keywords)
object.repairFields(keywords)
if again:
if keywords.has_key('data') and keywords['data']:
data = keywords['data']
if keywords.has_key('dataType') and \
isTypeOfMimeType(keywords['dataType'], 'image'):
uploadFileFile = cStringIO.StringIO(data)
uploadFileObject = PILImage.open(uploadFileFile)
width, height = uploadFileObject.size
keywords['width'] = str(width)
keywords['height'] = str(height)
keywords['size'] = str(len(data))
if keywords.has_key('data') and keywords['data']:
uri = X.idUrl(id, 'imageEdit')
uri.add('again', again)
uri.add('error', error)
uri.addKeywords(keywords)
else:
uri = None
keywords['dataUri'] = uri
if not object.id:
headerTitle = _('New %s') % _(self.objectNameCapitalized)
else:
headerTitle = _('Editing %s - %s') % (
_(self.objectNameCapitalized), object.getLabel())
context.push(_level = 'edit',
isCreateEditMode = not object.id,
layoutMode = 'edit')
try:
layout = X.array()
if error:
layout += object.getErrorLayout(keywords)
form = X.form(action = X.actionUrl('submit'),
enctype= 'multipart/form-data', method = 'post')
layout += form
if keywords.has_key('cloned') and keywords['cloned']:
form += X.input(name = 'cloned', type = 'hidden', value = '1')
slot = slots.Root(object)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, keywords)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
actionButtonsBar = X.span(_class = 'action-buttons-bar')
buttonsBar += actionButtonsBar
if not object.id:
actionButtonsBar += X.buttonInForm('create', 'createButton')
else:
# The button Delete is also added here, so that the user can
# delete the object he is editing without having to make it
# valid, clic modify and then delete it.
if self.canDeleteObject(object.id):
actionButtonsBar += X.buttonStandalone(
'delete', X.idUrl(object.id, 'confirmDelete'))
actionButtonsBar += X.buttonInForm('modify', 'modifyButton')
return writePageLayout(layout, headerTitle)
finally:
context.pull(_level = 'edit')
#uploadFileFile = cStringIO.StringIO(data)
#uploadFileObject = PILImage.open(uploadFileFile)
#width, height = uploadFileObject.size
def image(self, id, fileName = None):
if not self.hasObject(id):
@ -267,7 +200,7 @@ class UploadFilesWeb(ObjectsWebMixin, UploadFilesProxy):
if object.dataFileName:
req.headers_out['Content-Disposition'] = \
'inline; filename="%s"' % object.dataFileName
req.headers_out['Content-Length'] = str(object.size)
req.headers_out['Content-Length'] = str(object.size or 0)
if object.dataType:
req.content_type = object.dataType
setHttpCookie()
@ -276,7 +209,7 @@ class UploadFilesWeb(ObjectsWebMixin, UploadFilesProxy):
return OK
if req.caching:
req.openCachePage()
req.write(object.data)
req.write(object.data or '')
if req.caching:
req.closeCachePage()
return OK
@ -302,35 +235,17 @@ class UploadFilesWeb(ObjectsWebMixin, UploadFilesProxy):
return HTTP_NO_CONTENT
file.isPublicForWeb = ('PUT',)
def imageEdit(self, id = '', again = '', error = '', **keywords):
if keywords is None:
keywords = {}
keywords['id'] = id
if id and not self.hasObject(id):
return pageNotFound()
if id:
if not self.canModifyObject(id):
return accessForbidden()
object = self.getObject(id)
rememberObject(id)
else:
if not self.canAddObject():
return accessForbidden()
object = self.newObject(keywords)
if id and not again:
object.makeFieldsFromInstance(keywords)
if not id and not again:
object.initFields(keywords)
object.repairFields(keywords)
def imageEdit(self, dataToken, path = ''):
sessionsProxy = getProxyForServerRole('sessions')
data = sessionsProxy.getTemporaryData(dataToken)
req = context.getVar('req')
req.content_type = keywords['dataType']
req.content_type = data['type']
setHttpCookie()
req.send_http_header()
if req.method == 'HEAD':
return OK
req.write(keywords['data'])
req.write(data['data'])
return OK
imageEdit.isPublicForWeb = 1
@ -375,30 +290,23 @@ class UploadFilesWeb(ObjectsWebMixin, UploadFilesProxy):
object.data = 'fake data'
rememberObject(id)
keywords = {}
object.makeFieldsFromInstance(keywords)
object.repairFields(keywords)
if isTypeOfMimeType(object.dataType, 'image'):
fullUri = X.idUrl(id, 'image')
else:
fullUri = X.idUrl(id, 'download')
keywords['dataFullUri'] = fullUri
uri = X.idUrl(id, 'thumbnail')
uri.add('width', 256)
uri.add('height', 256)
keywords['dataUri'] = uri
label = object.getLabelTranslated(
context.getVar('readLanguages'))
label = object.getLabelTranslated(context.getVar('readLanguages'))
layout = X.array()
slot = slots.Root(object)
widget = slot.getWidget()
layout += widget.getModelPageBodyLayout(slot, keywords)
layout += self.getViewAboveButtonsBarLayout(object, keywords)
layout += self.getViewButtonsBarLayout(object, keywords)
layout += self.getViewBelowButtonsBarLayout(object, keywords)
layout += widget.getModelPageBodyLayout(slot, None)
layout += self.getViewAboveButtonsBarLayout(object, None)
layout += self.getViewButtonsBarLayout(object, None)
layout += self.getViewBelowButtonsBarLayout(object, None)
return writePageLayout(
layout, '%s - %s' % (_(self.objectNameCapitalized), label))
view.isPublicForWeb = 1

View File

@ -67,6 +67,7 @@ class VirtualHost(ObjectWebMixin, VirtualHost):
useBalloonHelp = 1
def initTemplateList(self):
# TODO: rewrite this in kind values getter
templatesDirectoryPath = context.getVar(
'templatesDirectoryPath')
dirs = os.listdir(templatesDirectoryPath)

View File

@ -73,17 +73,53 @@ class MarksWidget(widgets.BaseWidget):
idsGetter = getattr(container, idsGetterName)
objectIds = idsGetter(fields)
layout = X.array()
marks = slot.getValue()
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = slot.getFieldOption(fields, objectId, default = '')
mark = ''
if marks and marks.has_key(objectId):
mark = str(marks[objectId])
layout += X.input(name = fieldName, type = 'hidden',
value = mark),
return layout
def submit(self, slot, fields):
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
objectIds = idsGetter(fields) or []
isBlank = isButtonSelected(
slot.getFieldOptionName('blankButton'), fields)
result = {}
if isBlank:
# why not returning an empty dictionary ?
for objectId in objectIds:
result[objectId] = 0
return result
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = self.submitOneMark(slot, objectId, fields)
result[objectId] = mark
return result
def submitOneMark(self, slot, objectId, fields):
mark = slot.getFieldOption(fields, objectId)
try:
return int(mark)
except ValueError:
return None
class VoteApprovalMarksWidget(MarksWidget):
def submitOneMark(self, slot, objectId, fields):
mark = slot.getFieldOption(fields, objectId)
if not mark:
mark = '0'
return int(mark)
def getHtmlFieldValue(self, slot, fields, **keywords):
marks = slot.getValue()
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
@ -104,11 +140,15 @@ class VoteApprovalMarksWidget(MarksWidget):
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = slot.getFieldOption(fields, objectId, default = '')
mark = 0
if marks and marks.has_key(objectId) and marks[objectId]:
mark = marks[objectId]
if mark:
markSymbol = 'x'
else:
markSymbol = X.nbsp
tr = X.tr()
table += tr
if not self.isInForm() or self.isReadOnly(slot):
@ -116,10 +156,10 @@ class VoteApprovalMarksWidget(MarksWidget):
else:
td = X.td()
tr += td
errorCode = slot.getFieldOption(
fields, objectId + '_error')
if errorCode and not fields.has_key('hideErrors'):
td += X.asIs(makeErrorMessage(errorCode))
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
inputAttributes = {}
if mark:
inputAttributes['checked'] = 'checked'
@ -132,6 +172,7 @@ widgets.register(VoteApprovalMarksWidget)
class VoteDistributionMarksWidget(MarksWidget):
def getHtmlFieldValue(self, slot, fields, **keywords):
marks = slot.getValue()
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
@ -152,7 +193,9 @@ class VoteDistributionMarksWidget(MarksWidget):
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = slot.getFieldOption(fields, objectId, default = '')
mark = ''
if marks and marks.has_key(objectId) and marks[objectId]:
mark = '%.2f' % (marks[objectId]*100)
tr = X.tr()
table += tr
tr += X.td(X.objectHypertextLabel(objectId), X.asIs(_(':')))
@ -161,20 +204,35 @@ class VoteDistributionMarksWidget(MarksWidget):
else:
td = X.td()
tr += td
errorCode = slot.getFieldOption(
fields, objectId + '_error')
if errorCode and not fields.has_key('hideErrors'):
td += X.asIs(makeErrorMessage(errorCode))
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
td += X.input(maxlength = 6, name = fieldName, size = 6,
type = 'text', value = mark)
td += X.nbsp
td += '%'
return X.div(_class = 'cell')(layout)
def submitOneMark(self, slot, objectId, fields):
mark = slot.getFieldOption(fields, objectId) or ''
if mark and mark.strip():
try:
mark = float(mark) / 100.
except ValueError:
raise faults.BadValue()
mark = 0
else:
mark = 0
return mark
widgets.register(VoteDistributionMarksWidget)
class VoteRankingMarksWidget(MarksWidget):
def getHtmlFieldValue(self, slot, fields, **keywords):
marks = slot.getValue()
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
@ -195,7 +253,12 @@ class VoteRankingMarksWidget(MarksWidget):
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = slot.getFieldOption(fields, objectId, default = '')
mark = ''
if marks and marks.has_key(objectId) and marks[objectId]:
mark = marks[objectId]
mark = str(mark)
tr = X.tr()
table += tr
if not self.isInForm() or self.isReadOnly(slot):
@ -203,10 +266,10 @@ class VoteRankingMarksWidget(MarksWidget):
else:
td = X.td()
tr += td
errorCode = slot.getFieldOption(
fields, objectId + '_error')
if errorCode and not fields.has_key('hideErrors'):
td += X.asIs(makeErrorMessage(errorCode))
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
maxLength = len(str(len(objectIds)))
td += X.input(
maxlength = maxLength, name = fieldName,
@ -219,6 +282,7 @@ widgets.register(VoteRankingMarksWidget)
class VoteRatingMarksWidget(MarksWidget):
def getHtmlFieldValue(self, slot, fields, **keywords):
marks = slot.getValue()
container = slot.getContainer()
idsGetterName = slot.getKind().idsGetterName
idsGetter = getattr(container, idsGetterName)
@ -239,7 +303,9 @@ class VoteRatingMarksWidget(MarksWidget):
if objectIds:
for objectId in objectIds:
fieldName = slot.getFieldOptionName(objectId)
mark = slot.getFieldOption(fields, objectId, default = '')
mark = ''
if marks and marks.has_key(objectId) and marks[objectId]:
mark = marks[objectId]
tr = X.tr()
table += tr
tr += X.td()(X.objectHypertextLabel(objectId), X.asIs(_(':')))
@ -248,10 +314,10 @@ class VoteRatingMarksWidget(MarksWidget):
else:
td = X.td()
tr += td
errorCode = slot.getFieldOption(
fields, objectId + '_error')
if errorCode and not fields.has_key('hideErrors'):
td += X.asIs(makeErrorMessage(errorCode))
error = slot.getObject().getError(slot.getPath())
if error and not context.getVar('hideErrors'):
td += X.span(_class = 'error-message')(
_(error.uiFaultString))
td += X.input(maxlength = 6, name = fieldName, size = 6,
type = 'text', value = mark)
return X.div(_class = 'cell')(layout)
@ -272,8 +338,8 @@ class VoteMixin(ObjectWebMixin):
comment_kind_widget_rows = 4
comment_kind_widgetName = 'TextArea'
electionId_kind_hasToInitField = 0
electionId_kind_hasToMakeFieldFromValue = 0
#electionId_kind_hasToInitField = 0
#electionId_kind_hasToMakeFieldFromValue = 0
electionId_kind_hasToRepairField = 0
electionId_kind_hasToSubmitField = 0
electionId_kind_stateInEditMode = 'hidden'
@ -288,12 +354,17 @@ class VoteMixin(ObjectWebMixin):
electionToken_kind_widget_fieldLabel = N_('Election Token')
electionToken_kind_widgetName = 'Token'
subject = None
subject_kind_isTranslatable = 0
subject_kind_stateInEditMode = 'read-only'
subject_kindName = 'String'
token_kind_stateInEditMode = 'read-only'
token_kind_widget_fieldLabel = N_('Vote Token')
token_kind_widgetName = 'Token'
voterId_kind_hasToInitField = 0
voterId_kind_hasToMakeFieldFromValue = 0
#voterId_kind_hasToInitField = 0
#voterId_kind_hasToMakeFieldFromValue = 0
voterId_kind_hasToRepairField = 0
voterId_kind_hasToSubmitField = 0
voterId_kind_stateInEditMode = 'read-only'
@ -307,15 +378,19 @@ class VoteMixin(ObjectWebMixin):
voterToken_kind_widgetName = 'Token'
def getElectionCandidateIds(self, fields):
return fields['election'].candidateIds
return getObject(self.electionId).candidateIds
def getEditLayout(self, fields, parentSlot = None):
election = fields['election']
election = getObject(self.electionId)
slot = election.getSlot('subject')
subject, destinationLanguage, state = \
getProxyForServerRole('translations').getTranslationInfos(
election.subject, election.getId(), slot.getPath(),
election.getLanguage(), context.getVar('readLanguages'))
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
subject, destinationLanguage, state = \
translationsProxy.getTranslationInfos(
election.subject, election.getId(), slot.getPath(),
election.getLanguage(), context.getVar('readLanguages'))
else:
subject = election.subject
self.subject = subject
self.subject_kind = copy.copy(election.subject_kind)
self.subject_kind.stateInEditMode = 'read-only'
@ -339,22 +414,26 @@ class VoteMixin(ObjectWebMixin):
self, fields, parentSlot = parentSlot)
hiddenSlotNames = hiddenSlotNames[:]
slot = self.getSlot('voterId')
if slot.getField(fields):
if slot.getValue():
hiddenSlotNames.append('voterToken')
else:
hiddenSlotNames.append('voterId')
election = fields['election']
election = getObject(self.electionId)
if election.ballotKind != 'voterChoice':
hiddenSlotNames.append('ballotKind')
return hiddenSlotNames
def getViewLayout(self, fields, parentSlot = None):
election = fields['election']
election = getObject(self.electionId)
slot = election.getSlot('subject')
subject, destinationLanguage, state = \
getProxyForServerRole('translations').getTranslationInfos(
election.subject, election.getId(), slot.getPath(),
election.getLanguage(), context.getVar('readLanguages'))
translationsProxy = getProxyForServerRole('translations')
if translationsProxy:
subject, destinationLanguage, state = \
translationsProxy.getTranslationInfos(
election.subject, election.getId(), slot.getPath(),
election.getLanguage(), context.getVar('readLanguages'))
else:
subject = election.subject
self.subject = subject
self.subject_kind = copy.copy(election.subject_kind)
self.subject_kind.isTranslatable = 0
@ -377,40 +456,15 @@ class VoteMixin(ObjectWebMixin):
self, fields, parentSlot = parentSlot)
hiddenSlotNames = hiddenSlotNames[:]
slot = self.getSlot('voterId')
if slot.getField(fields):
if slot.getValue():
hiddenSlotNames.append('voterToken')
else:
hiddenSlotNames.append('voterId')
election = fields['election']
election = getObject(self.electionId)
if election.ballotKind != 'voterChoice':
hiddenSlotNames.append('ballotKind')
return hiddenSlotNames
def makeFieldsFromInstance(self, fields, parentSlot = None):
if self.isBlank(self.getElectionCandidateIds(fields)):
# Duplicate the marks kind.
slot = self.getSlot('marks', parentSlot = parentSlot)
self.marks_kind = copy.copy(self.marks_kind)
self.marks_kind.hasToMakeFieldFromValue = 0
ObjectWebMixin.makeFieldsFromInstance(
self, fields, parentSlot = parentSlot)
slot.getKind().makeFieldFromValue(slot, fields, {})
# Delete the duplicated marks kind.
del self.marks_kind
else:
ObjectWebMixin.makeFieldsFromInstance(
self, fields, parentSlot = parentSlot)
def submitFields(self, fields, parentSlot = None):
election = fields['election']
# Duplicate the ballotKind kind.
slot = self.getSlot('ballotKind', parentSlot = parentSlot)
self.ballotKind_kind = copy.copy(self.ballotKind_kind)
self.ballotKind_kind.hasToSubmitField = \
election.ballotKind == 'voterChoice'
ObjectWebMixin.submitFields(self, fields, parentSlot = parentSlot)
# Delete the duplicated ballotKind kind.
del self.ballotKind_kind
class AbstractVote(VoteMixin, AbstractVote):
pass
@ -637,15 +691,10 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
def canAddObject(self, serverId = None):
return 0
def edit(self, id = '', electionId = '', again = '', error = '',
**keywords):
def edit(self, id = '', electionId = ''):
ballotsWeb = getWebForServerRole('ballots')
electionsWeb = getWebForServerRole('elections')
peopleWeb = getWebForServerRole('people')
if keywords is None:
keywords = {}
keywords['id'] = id
keywords['electionId'] = electionId
userId = context.getVar('userId', default = '')
userToken = context.getVar('userToken', default = '')
if not userToken:
@ -682,28 +731,25 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
vote = ballotsWeb.getVoteFromToken(voteToken)
except faults.UnknownVoteToken:
vote = election.newVote()
vote.fillWithDefaultValues()
else:
id = vote.id
rememberObject(id)
else:
vote = election.newVote()
keywords['election'] = election
if id and not again:
vote.makeFieldsFromInstance(keywords)
if not id and not again:
vote.initFields(keywords)
vote.repairFields(keywords)
return self.editObject(vote, electionId)
edit.isPublicForWeb = 1
slot = vote.getSlot('electionId')
slot.getKind().makeFieldFromValue(slot, keywords, electionId)
slot = election.getSlot('subject')
slot.getKind().makeFieldFromValue(
slot, keywords, election.subject)
slot = vote.getSlot('voterId')
slot.getKind().makeFieldFromValue(slot, keywords, userId)
def editObject(self, vote, electionId = ''):
electionsWeb = getWebForServerRole('elections')
election = electionsWeb.getObject(electionId)
userId = context.getVar('userId', default = '')
vote.getSlot('electionId').setValue(electionId)
vote.getSlot('voterId').setValue(userId)
vote.getSlot('subject').setValue(election.subject)
if not id:
if not vote.id:
headerTitle = _('New %s') % _(self.objectNameCapitalized)
else:
headerTitle = _('Editing %s - %s') % (
@ -712,16 +758,15 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
context.push(_level = 'edit', layoutMode = 'edit')
try:
layout = X.array()
if error:
layout += vote.getErrorLayout(keywords)
if context.getVar('error'):
layout += vote.getErrorLayout()
form = X.form(action = X.actionUrl('submit'),
enctype= 'multipart/form-data', method = 'post')
layout += form
slot = slots.Root(vote)
widget = slot.getWidget()
form += widget.getModelPageBodyLayout(slot, keywords)
del keywords['election']
form += widget.getModelPageBodyLayout(slot, None)
buttonsBar = X.div(_class = 'buttons-bar')
form += buttonsBar
@ -736,7 +781,6 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
return writePageLayout(layout, headerTitle)
finally:
context.pull(_level = 'edit')
edit.isPublicForWeb = 1
def submit(self, id = '', electionId = '', **keywords):
ballotsWeb = getWebForServerRole('ballots')
@ -744,10 +788,8 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
if keywords is None:
keywords = {}
keywords['id'] = id
keywords['electionId'] = electionId
userId = context.getVar('userId', default = '')
userToken = context.getVar('userToken', default = '')
error = 0
if not userToken:
return accessForbidden()
if not electionId \
@ -756,8 +798,8 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
if not electionsWeb.canVote(electionId):
return accessForbidden()
if isButtonSelected('applyButton', keywords):
keywords['again'] = '1'
keywords['hideErrors'] = '1'
context.setVar('again', 1)
context.setVar('hideErrors', 1)
elif isButtonSelected('abstainButton', keywords):
try:
ballotsWeb.abstainForVote(electionId)
@ -769,22 +811,18 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
'electionId', electionId).add('voterId', userId))
election = electionsWeb.getObject(electionId)
vote = election.newVote()
if error:
keywords['again'] = '1'
keywords['error'] = '1'
else:
keywords['election'] = election
vote.submitFields(keywords)
del keywords['election']
if keywords.has_key('again') and keywords['again']:
uri = X.idUrl(id, 'edit')
uri.add('electionId', electionId)
uri.addKeywords(keywords)
return redirect(uri)
#try:
id = ballotsWeb.vote(electionId, vote)
#except faults.Fault:
# return accessForbidden()
vote.getSlot('electionId').setValue(electionId)
keywords['election'] = election
vote.submitFields(keywords)
del keywords['election']
if context.getVar('again'):
return self.editObject(vote, electionId)
try:
id = ballotsWeb.vote(electionId, vote)
except faults.WrongVersion:
context.setVar('error', 1)
vote.setError('version', 1)
return self.editObject(vote, electionId)
return redirect(X.idUrl(id))
submit.isPublicForWeb = 1
@ -840,18 +878,12 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
else:
vote = election.newVote()
vote.getSlot('electionId').setValue(electionId)
vote.getSlot('voterId').setValue(userId)
vote.getSlot('subject').setValue(election.subject)
keywords = {}
keywords['election'] = election
vote.makeFieldsFromInstance(keywords)
vote.repairFields(keywords)
slot = vote.getSlot('electionId')
slot.getKind().makeFieldFromValue(slot, keywords, electionId)
slot = election.getSlot('subject')
slot.getKind().makeFieldFromValue(
slot, keywords, election.subject)
slot = vote.getSlot('voterId')
slot.getKind().makeFieldFromValue(slot, keywords, voterId)
label = election.getLabelTranslated(
context.getVar('readLanguages'))
@ -859,7 +891,7 @@ class VotesWeb(ObjectsWebMixin, VotesProxy):
layout = X.array()
slot = slots.Root(vote)
widget = slot.getWidget()
layout += widget.getModelPageBodyLayout(slot, keywords)
layout += widget.getModelPageBodyLayout(slot, None)
del keywords['election']
layout += X.br()
if voterId and voterId == userId and electionsWeb.canVote(electionId):

View File

@ -510,7 +510,7 @@ def template(filename, xtal=0, **keywords):
program, macros = t.getCode()
from TAL.TALInterpreter import TALInterpreter
from GlasnostTALInterpreter import GlasnostTALInterpreter
from GlasnostTALEngine import GlasnostTALEngine
engine = GlasnostTALEngine(macros)
#context.setVar('talEngine', engine)
@ -518,7 +518,7 @@ def template(filename, xtal=0, **keywords):
for k, v in keywords.items():
engine.locals[k] = v
stream = tools.StringIO()
interp = TALInterpreter(program, macros, engine, stream=stream, wrap=80)
interp = GlasnostTALInterpreter(program, macros, engine, stream=stream, wrap=80)
interp()
return stream.getvalue()

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,7 @@ __version__ = '$Revision$'[11:-2]
import copy
import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
@ -63,51 +64,6 @@ class Aspect(things.ThingMixin, proxyModes.Aspect):
kind = None # Not a slot
slot = None # Not a slot.
class widget_kindClass(proxyModes.Aspect.widget_kindClass):
def repairField(self, slot, fields, forceEmbedding = 0, **keywords):
if forceEmbedding or self.isModelEmbedded(slot):
return self.getRealKindClass().repairField(
self, slot, fields, forceEmbedding = forceEmbedding,
**keywords)
values = self.getValues(slot, fields)
if values and not slot.getField(fields) in values:
fieldValue = values[0]
slot.setField(fields, fieldValue)
def submitField2(self, slot, fields, forceEmbedding = 0, **keywords):
if forceEmbedding or self.isModelEmbedded(slot):
return self.getRealKindClass().submitField2(
self, slot, fields, forceEmbedding = forceEmbedding,
**keywords)
fieldValue = slot.getField(fields, default = '')
error = 0
errorFields = {}
value = None
values = self.getValues(slot, fields)
if not fieldValue:
if self.isRequired:
error = 1
slot.setFieldOption(errorFields, 'error', 'missingValue')
else:
value = None
else:
try:
oldValue = slot.getValue()
except:
oldValue = None
if not fieldValue in values and (
oldValue is None
or oldValue.getThingName() != fieldValue):
error = 2
slot.setFieldOption(errorFields, 'error', 'wrongValue')
else:
value = commonTools.newThing(
self.valueThingCategory, fieldValue)
if oldValue is not None \
and oldValue.getThingName() == value.getThingName():
value = oldValue
return (error, errorFields, value)
def isModelHidden(self):
return self.state == 'hidden' \
or self.state == 'read-only/hidden-if-empty' \
@ -131,11 +87,6 @@ class ModeMixin(things.ThingMixin):
context.getVar('readLanguages'))
return headerTitle
def makeModelFields(self, object, fields, again, parentSlot = None):
if not again:
object.makeFieldsFromInstance(fields, parentSlot = parentSlot)
object.repairFields(fields, parentSlot = parentSlot)
class ModeAbstract(ModeMixin, proxyModes.ModeAbstract):
pass
@ -150,8 +101,7 @@ class Custom(ModeMixin, proxyModes.Custom):
kind = slot.getKind()
kind.executeModel(slot, when, command = command)
def getModelLayoutInfos(self, object, fields, again, create,
parentSlot = None):
def getModelLayoutInfos(self, object, fields, create, parentSlot = None):
inForm = 0
if self.aspects:
aspects = []
@ -172,7 +122,6 @@ class Custom(ModeMixin, proxyModes.Custom):
for aspect in aspects:
aspect.kind.executeModel(aspect.slot, 'onDisplay')
self.makeModelFields(object, fields, again, parentSlot = parentSlot)
headerTitle = self.getModelHeaderTitle(
object, fields, parentSlot = parentSlot)
@ -246,15 +195,32 @@ class Custom(ModeMixin, proxyModes.Custom):
return self.usersSet
def submitModelFields(self, object, fields, parentSlot = None):
object.delErrors()
for slotName in object.getRequiredFieldSlotNames(
fields, parentSlot = parentSlot):
if slotName in ['thingCategory', 'thingName']:
continue
slot = object.getSlot(slotName, parentSlot = parentSlot)
kind = slot.getKind()
widget = slot.getWidget()
if (kind.isRequiredInEditMode or kind.isExportable()) \
and kind.hasToSubmitField:
kind.submitField(slot, fields)
try:
value = widget.submit(slot, fields)
if value is not None and \
type(value) != kind.pythonStorageType:
value = kind.convertValueFromOtherType(value)
if kind.isEmptyModelValue(slot, value):
value = None
kind.checkModelValue(slot, value)
except faults.BaseFault, f:
self.setError(slot.getPath(), f)
context.setVar('again', 1)
context.setVar('error', 1)
if not slot.hasValue() or value != slot.getValue():
slot.setValue(value)
if self.aspects:
for aspect in self.aspects:
@ -262,7 +228,21 @@ class Custom(ModeMixin, proxyModes.Custom):
continue
slot = object.getSlot(aspect.name, parentSlot = parentSlot)
kind = slot.getKind()
kind.submitField(slot, fields)
widget = slot.getWidget()
try:
value = widget.submit(slot, fields)
if value is not None and \
type(value) != kind.pythonStorageType:
value = kind.convertValueFromOtherType(value)
if kind.isEmptyModelValue(slot, value):
value = None
kind.checkModelValue(slot, value)
except faults.BaseFault, f:
self.setError(slot.getPath(), f)
context.setVar('again', 1)
context.setVar('error', 1)
slot.setValue(value)
register(Custom)
@ -278,9 +258,7 @@ class Edit(ModeMixin, proxyModes.Edit):
_(web.objectNameCapitalized), label)
return headerTitle
def getModelLayoutInfos(self, object, fields, again, create,
parentSlot = None):
self.makeModelFields(object, fields, again, parentSlot = parentSlot)
def getModelLayoutInfos(self, object, fields, create, parentSlot = None):
headerTitle = self.getModelHeaderTitle(
object, fields, parentSlot = parentSlot)
@ -324,9 +302,7 @@ class View(ModeMixin, proxyModes.View):
headerTitle = '%s - %s' % (_(web.objectNameCapitalized), label)
return headerTitle
def getModelLayoutInfos(self, object, fields, again, create,
parentSlot = None):
self.makeModelFields(object, fields, again, parentSlot = parentSlot)
def getModelLayoutInfos(self, object, fields, create, parentSlot = None):
headerTitle = self.getModelHeaderTitle(
object, fields, parentSlot = parentSlot)

View File

@ -53,7 +53,7 @@ import glasnost.common.xhtmlgenerator as X
import glasnost.proxy.things as proxyThings
from tools import getWebForServerRole
from tools import getWebForServerRole, isButtonSelected
class ThingClasses(commonThings.ThingClasses):
@ -74,6 +74,12 @@ def register(thingClass):
class ThingMixin:
errors = None
def fillWithDefaultValues(self, parentSlot = None):
for slotName in self.getSlotNames(parentSlot = parentSlot):
slot = self.getSlot(slotName, parentSlot = parentSlot)
kind = slot.getKind()
kind.setToDefaultValue(slot)
def getCompactEditLayout(self, fields, parentSlot = None):
if parentSlot is None:
level = 'getCompactEditLayout'
@ -156,7 +162,7 @@ class ThingMixin:
def getEditLayoutSlotNames(self, fields, parentSlot = None):
slotNames = self.getLayoutSlotNames(fields, parentSlot = parentSlot)
if not fields.has_key('id') or not fields['id']:
if hasattr(self, 'id') and not self.id:
slotNamesToRemove = ['creationTime', 'lastEditorId',
'modificationTime']
for slotName in slotNamesToRemove:
@ -164,18 +170,20 @@ class ThingMixin:
slotNames.remove(slotName)
return slotNames
def getErrorLayout(self, keywords):
if keywords.has_key('hideErrors'):
def getErrorLayout(self):
if context.getVar('hideErrors'):
return None
div = X.div(_class = 'error-message')
div += X.h1(_('Error!'))
if keywords.has_key('versionError') and keywords['versionError']:
if self.getError('version'):
div += X.p()(
_("""\
The informations have been changed while you were editing them.
Please backup your changes and redo the edition.\
"""))
div += X.buttonStandalone(
_('Look at new version'), X.idUrl(self.id))
return div
def getFieldSlotNames(self, fields, parentSlot = None):
@ -231,7 +239,7 @@ Please backup your changes and redo the edition.\
return slotNames
def getOrderedFieldSlotNames(self, fields, parentSlot = None):
return []
return self.getOrderedLayoutSlotNames(parentSlot)
def getViewLayout(self, fields, parentSlot = None):
context.push(_level = 'getViewLayout',
@ -272,42 +280,18 @@ Please backup your changes and redo the edition.\
def getViewLayoutSlotNames(self, fields, parentSlot = None):
return self.getLayoutSlotNames(fields, parentSlot = parentSlot)
def initFields(self, fields, parentSlot = None):
for slotName in self.getFieldSlotNames(
fields, parentSlot = parentSlot):
slot = self.getSlot(slotName, parentSlot = parentSlot)
kind = slot.getKind()
if kind.hasToInitField:
kind.initField(slot, fields)
def makeFieldsFromInstance(self, fields, parentSlot = None):
for slotName in self.getFieldSlotNames(
fields, parentSlot = parentSlot):
slot = self.getSlot(slotName, parentSlot = parentSlot)
kind = slot.getKind()
if kind.hasToMakeFieldFromValue:
if slotName == 'thingName':
value = self.getThingName()
else:
value = slot.getValue()
kind.makeFieldFromValue(slot, fields, value)
def newWidget(self, parentSlot = None):
return commonTools.newThing('widget', 'Thing')
def repairFields(self, fields, parentSlot = None):
for slotName in self.getFieldSlotNames(
fields, parentSlot = parentSlot):
slot = self.getSlot(slotName, parentSlot = parentSlot)
kind = slot.getKind()
if kind.hasToRepairField:
kind.repairField(slot, fields)
def getError(self, slotName):
if not self.errors or not self.errors.has_key(slotName):
return None
return self.errors[slotName]
def hasErrors(self):
# not not so we get a boolean
return not not self.errors
def setError(self, slotPath, error):
if not self.errors:
self.errors = {}
@ -317,15 +301,21 @@ Please backup your changes and redo the edition.\
self.errors = {}
def submitFields(self, fields, parentSlot = None):
self.delErrors()
#self.delErrors()
if isButtonSelected('applyButton', fields):
context.setVar('again', 1)
context.setVar('hideErrors', 1)
# Change the class of the thing if needed.
for slotName in ['thingCategory', 'thingName']:
slot = self.getSlot(slotName, parentSlot = parentSlot)
widget = slot.getWidget()
kind = slot.getKind()
if (kind.isRequiredInEditMode or kind.isExportable()) \
and kind.hasToSubmitField:
kind.submitField(slot, fields)
value = widget.submit(slot, fields)
slot.setValue(value)
thingCategory = self.thingCategory
if self.__dict__.has_key('thingCategory'):
del self.thingCategory
@ -336,8 +326,13 @@ Please backup your changes and redo the edition.\
del self.thingName
if thingCategory != self.thingCategory \
or thingName != self.getThingName():
self.__class__ = commonTools.getThingClass(
try:
self.__class__ = commonTools.getThingClass(
thingCategory, thingName)
except:
pass
# FIXME: I don't know what I'm doing
# (was necessary to get properties (in cards) working
for slotName in self.getFieldSlotNames(
fields, parentSlot = parentSlot):
@ -349,22 +344,23 @@ Please backup your changes and redo the edition.\
if (kind.isRequiredInEditMode or kind.isExportable()) \
and kind.hasToSubmitField:
try:
valueKind, value = widget.submit(slot, fields)
if valueKind is not None:
value = kind.convertValueFromOtherKind(
value, valueKind)
value = widget.submit(slot, fields)
if value is not None and \
type(value) != kind.pythonStorageType:
value = kind.convertValueFromOtherType(value)
if kind.isEmptyModelValue(slot, value):
value = None
kind.checkModelValue(slot, value)
except faults.BaseFault, f:
self.setError(slot.getPath(), f)
fields['again'] = '1'
fields['error'] = '1'
context.setVar('again', 1)
context.setVar('error', 1)
continue
#except NotImplementedError:
# kind.submitField(slot, fields)
if not slot.hasValue() or value != slot.getValue():
slot.setValue(value)
class BaseThing(ThingMixin, proxyThings.BaseThing):
pass

View File

@ -326,6 +326,9 @@ def isTypeOfMimeType(mimeType, type):
def makeErrorMessage(error):
# this function is no longer used;
# it is kept since it has some strings that I want to keep in gettext
# for future use.
if error == 'can\'tChangeValue':
message = N_('Can\'t change value!')
elif error == 'duplicateValue':
@ -647,10 +650,9 @@ def getTemplateVars():
shortNewsLabel = _('Short News')
session = context.getVar('session')
if session and session.has_key('userId'):
if userId:
try:
userName = getObject(session['userId']).getLabel()
userName = getObject(userId).getLabel()
except (faults.MissingItem, faults.UserAccessDenied):
userName = _('Unknown')
else:
@ -722,7 +724,8 @@ def writePageLayout(layout, title, canCache = 1):
program, macros = t.getCode()
# this takes roughly 0.01 seconds, not worth caching
from TAL.TALInterpreter import TALInterpreter
from GlasnostTALInterpreter import GlasnostTALInterpreter
from TAL.HTMLParser import HTMLParseError
from GlasnostTALEngine import GlasnostTALEngine, TALError
engine = GlasnostTALEngine(macros)
context.setVar('talEngine', engine)
@ -732,7 +735,7 @@ def writePageLayout(layout, title, canCache = 1):
for k, v in dict.items():
engine.locals[k] = v
interp = TALInterpreter(program, macros, engine, stream=req, wrap=80)
interp = GlasnostTALInterpreter(program, macros, engine, stream=req, wrap=80)
try:
interp()
except TALError:
@ -976,7 +979,7 @@ def processTALFile(fileName, file = None, xtal = None, **keywords):
t.parseString(file)
program, macros = t.getCode()
from TAL.TALInterpreter import TALInterpreter
from GlasnostTALInterpreter import GlasnostTALInterpreter
from GlasnostTALEngine import GlasnostTALEngine, TALError
engine = GlasnostTALEngine(macros)
context.setVar('talEngine', engine)
@ -988,7 +991,7 @@ def processTALFile(fileName, file = None, xtal = None, **keywords):
for k, v in dict.items():
engine.locals[k] = v
interp = TALInterpreter(program, macros, engine, stream=req, wrap=80)
interp = GlasnostTALInterpreter(program, macros, engine, stream=req, wrap=80)
try:
interp()
except TALError:

View File

@ -58,6 +58,24 @@ import glasnost.common.tools_new as commonTools
import glasnost.common.xhtmlgenerator as X
def addContextualHeader(htmlLine):
knownLines = {
'tooltips.js':
'<script src="%s" type="text/javascript"></script>' % \
X.fileUrl('/javascript/tooltips.js'),
'calendar.css':
'<link href="%s" rel="stylesheet" type="text/css" />' % \
X.fileUrl('/css/calendar.css'),
'noindex':
'<meta name="robots" content="noindex" />',
}
if htmlLine in knownLines.keys():
htmlLine = knownLines[htmlLine]
contextualHeaders = context.getVar('htmlHeaders')
if not htmlLine in contextualHeaders:
contextualHeaders.append(htmlLine)
def debugInfos():
req = context.getVar('req')
req.content_type = 'text/html'
@ -138,20 +156,3 @@ def getConfig(value, default = None, vars = None, raw = 0):
default = commonTools.getConfig('Misc', value, default, vars, raw),
vars = vars, raw = raw)
def addContextualHeader(htmlLine):
knownLines = {
'tooltips.js':
'<script src="%s" type="text/javascript"></script>' % \
X.fileUrl('/javascript/tooltips.js'),
'calendar.css':
'<link href="%s" rel="stylesheet" type="text/css" />' % \
X.fileUrl('/css/calendar.css'),
'noindex':
'<meta name="robots" content="noindex" />',
}
if htmlLine in knownLines.keys():
htmlLine = knownLines[htmlLine]
contextualHeaders = context.getVar('htmlHeaders')
if not htmlLine in contextualHeaders:
contextualHeaders.append(htmlLine)

View File

@ -64,7 +64,10 @@ def getFieldTranslated(object, field, keywords):
def getFieldValueAndTranslationBar(slot, noBar = 0):
value = slot.getValue()
value = slot.getKind().convertValueToOtherKind(value, kinds.String())
if type(value) is not types.StringType:
value = slot.getKind().convertValueToOtherType(value, types.StringType)
if not value:
return value, None

View File

@ -105,12 +105,12 @@ class Upload(things.ThingMixin, proxyUploads.Upload):
def getEditLayout(self, fields, parentSlot = None):
dataSlot = self.getSlot('data', parentSlot = parentSlot)
data = dataSlot.getField(fields)
data = dataSlot.getValue()
sizeSlot = self.getSlot('size', parentSlot = parentSlot)
if data and not sizeSlot.getField(fields):
if data and not sizeSlot.getValue():
sizeSlot.setField(fields, str(len(data)))
dataTypeSlot = self.getSlot('dataType', parentSlot = parentSlot)
if isTypeOfMimeType(dataTypeSlot.getField(fields, default = ''),
if isTypeOfMimeType(dataTypeSlot.getValue() or '',
'image') and PILImage:
imageFile = cStringIO.StringIO(data)
try:
@ -141,8 +141,8 @@ class Upload(things.ThingMixin, proxyUploads.Upload):
slotNames = things.ThingMixin.getViewLayoutSlotNames(
self, fields, parentSlot = parentSlot)
slotNames = slotNames[:]
if not fields.has_key('dataType') \
or not isTypeOfMimeType(fields['dataType'], 'image'):
if not self.dataType or \
not isTypeOfMimeType(self.dataType, 'image'):
if 'height' in slotNames:
slotNames.remove('height')
if 'width' in slotNames:
@ -154,14 +154,4 @@ class Upload(things.ThingMixin, proxyUploads.Upload):
if slotName in slotNames:
slotNames.remove(slotName)
return slotNames
def makeFieldsFromInstance(self, fields, parentSlot = None):
for slotName in ('height', 'width'):
self.getSlot(slotName, parentSlot = parentSlot).getKind(
).hasToMakeFieldFromValue = self.isType('image')
things.ThingMixin.makeFieldsFromInstance(
self, fields, parentSlot = parentSlot)
for slotName in ('height', 'width'):
del self.getSlot(slotName, parentSlot = parentSlot).getKind(
).hasToMakeFieldFromValue
things.register(Upload)

View File

@ -49,8 +49,9 @@ __version__ = '$Revision$'[11:-2]
import locale
import time
import re
import time
import types
import urllib
import glasnost.common.context as context
@ -100,9 +101,8 @@ class WidgetMixin(things.ThingMixin):
label.setAttribute('class', ' '.join(
[label.getAttribute('class'), 'fullwidth']))
if slot.getObject().getError(slot.getPath() or
slot.getFieldOption(fields, 'error')) and \
not fields.has_key('hideErrors'):
if slot.getObject().getError(slot.getPath()) and \
not context.getVar('hideErrors'):
layout.setAttribute('class', ' '.join(
[layout.getAttribute('class'), 'error']))
layout += cell
@ -171,8 +171,8 @@ class WidgetMixin(things.ThingMixin):
return self.getHtmlFormValue(slot, fields, **keywords)
def getHtmlViewValue(self, slot, fields, **keywords):
fieldValue = slot.getField(fields, default = '')
format = slot.getKind().textFormat
fieldValue = slot.getValue() or ''
format = slot.getKind().getTextFormat(slot)
if format == 'html':
formattedText = parsers.makeHtmlFromHtml(fieldValue, inline = 1)
elif format == 'text':
@ -196,7 +196,7 @@ class WidgetMixin(things.ThingMixin):
def getHtmlFormValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = slot.getField(fields, default = '')
fieldValue = slot.getValue() or ''
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
layout += self.getModelHelpLayout(slot, fields)
@ -206,24 +206,18 @@ class WidgetMixin(things.ThingMixin):
return layout
def getModelErrorLayout(self, slot, fields):
if fields.has_key('hideErrors'):
if context.getVar('hideErrors'):
return None
try:
error = slot.getObject().getError(slot.getPath())
except:
raise repr(slot)
except (TypeError, IndexError):
error = None
if error:
return X.span(_class = 'error-message')(
_(error.uiFaultString))
errorCode = slot.getFieldOption(fields, 'error')
if errorCode:
return X.asIs(makeErrorMessage(errorCode))
return None
def getModelFieldLayout(self, slot, fields, **keywords):
assert fields is not None
kind = slot.getKind()
tagName = kind.getModelFieldTag(slot)
if tagName == 'div-with-label':
@ -255,12 +249,13 @@ class WidgetMixin(things.ThingMixin):
def getModelHiddenLayout(self, slot, fields):
fieldName = slot.getFieldName()
fieldValue = ''
try:
fieldValue = slot.getValue()
except TypeError:
pass
return X.input(name = fieldName, type = 'hidden', value = fieldValue)
value = slot.getValue()
if value is None:
value = ''
if type(value) is not types.StringType:
value = slot.getKind().convertValueToOtherType(
value, types.StringType)
return X.input(name = fieldName, type = 'hidden', value = value)
def getModelPageBodyLayout(self, slot, fields):
layoutMode = context.getVar('layoutMode')
@ -272,12 +267,14 @@ class WidgetMixin(things.ThingMixin):
layout = self.getHtmlFormValue(slot, fields)
return layout
def submitEmbedded(self, slot, fields):
kind = slot.getKind()
parentSlot, value = kind.getCreatedModelSlotAndValue(slot)
value.submitFields(fields, parentSlot = parentSlot)
return value
def submit(self, slot, fields):
fieldName = slot.getFieldName()
fieldValue = str(slot.getField(fields, default = ''))
if not fieldValue:
return None, None
return kinds.String(), fieldValue
return slot.getField(fields) or None
class InputTextMixin(WidgetMixin):
@ -287,7 +284,7 @@ class InputTextMixin(WidgetMixin):
if not fieldValue:
fieldValue = ''
format = slot.getKind().textFormat
format = slot.getKind().getTextFormat(slot)
if format == 'html':
formattedText = parsers.makeHtmlFromHtml(fieldValue, inline = 1)
elif format == 'text':
@ -313,7 +310,12 @@ class InputTextMixin(WidgetMixin):
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
fieldValue = slot.getValue()
format = slot.getKind().textFormat
if type(fieldValue) is not types.StringType:
fieldValue = slot.getKind().convertValueToOtherType(fieldValue,
types.StringType)
format = slot.getKind().getTextFormat(slot)
if format == 'html':
formattedText = parsers.makeHtmlFromHtml(fieldValue, inline = 1)
elif format == 'text':
@ -335,7 +337,11 @@ class InputTextMixin(WidgetMixin):
def getHtmlFormValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = str(slot.getField(fields, default = ''))
fieldValue = slot.getValue()
if type(fieldValue) is not types.StringType:
fieldValue = slot.getKind().convertValueToOtherType(fieldValue,
types.StringType)
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
@ -361,12 +367,11 @@ class InputTextMixin(WidgetMixin):
return layout
def submit(self, slot, fields):
fieldName = slot.getFieldName()
fieldValue = str(slot.getField(fields, default = ''))
if not fieldValue:
return None, None
fieldValue = fieldValue.replace('\r\n', '\n')
fieldValue = fieldValue.replace(
value = WidgetMixin.submit(self, slot, fields)
if value is None:
return None
value = value.replace('\r\n', '\n')
value = value.replace(
'\x91', "'").replace('\x92', "'").replace(
'\x93', "'").replace('\x94', "'").replace(
'\x81', "'").replace('\x82', "'").replace(
@ -374,7 +379,7 @@ class InputTextMixin(WidgetMixin):
'&#8211;', '--').replace('&#8220;', '"').replace(
'&#180;', "'").replace('&#8221;', '"').replace(
'&#8216;', "'")
return kinds.String(), fieldValue
return value
class ThingMixin(WidgetMixin):
@ -407,6 +412,28 @@ class ThingMixin(WidgetMixin):
layout = value.getViewLayout(fields, parentSlot = parentSlot)
return layout
def submit(self, slot, fields):
# TODO: clarify things in my head
kind = slot.getKind()
parentSlot, value = kind.getCreatedModelSlotAndValue(slot)
value.submitFields(fields, parentSlot)
return value # ?
value = WidgetMixin.submit(self, slot, fields)
if not value:
return None
try:
oldValue = slot.getValue()
except:
oldValue = None
kind = slot.getKind()
value = commonTools.newThing(
kind.valueThingCategory, value)
if oldValue is not None and \
oldValue.getThingName() == value.getThingName():
value = oldValue
return value
class TimeMixin(InputTextMixin):
pass
@ -436,7 +463,6 @@ class Amount(WidgetMixin, proxyWidgets.Amount):
X.nbsp,
X.asIs(_(sideFieldLabel)),
)
def getHtmlFormValue(self, slot, fields, **keywords):
mainFieldName = slot.getFieldOptionName('main')
@ -492,6 +518,14 @@ class Amount(WidgetMixin, proxyWidgets.Amount):
X.input(name = sideFieldName, type = 'hidden',
value = sideFieldValue),
)
def submit(self, slot, fields):
value = int(slot.getFieldOption(fields, 'main',
default = '0')) * 100 + \
int(slot.getFieldOption(fields, 'cents', default = '0'))
if slot.getFieldOption(fields, 'side', default = '') == 'debit':
value = -value
return value
register(Amount)
@ -607,7 +641,7 @@ class Date(TimeMixin, proxyWidgets.Date):
def submit(self, slot, fields):
try:
return kinds.Time(), time.mktime( [
return time.mktime( [
int(slot.getFieldOption(fields, 'year', default = '')),
int(slot.getFieldOption(fields, 'month', default = '')),
int(slot.getFieldOption(fields, 'day', default = '')) ] +
@ -693,6 +727,21 @@ class Duration(WidgetMixin, proxyWidgets.Duration):
X.input(name = dayFieldName, type = 'hidden',
value = dayFieldValue),
)
def submit(self, slot, fields):
factors = {
'second' : 1,
'minute' : 60,
'hour' : 60*60,
'day' : 24*60*60
}
try:
return reduce(lambda x,y:x+y,
[int(slot.getFieldOption(
fields, z, default = '0')) * factors[z]
for z in factors.keys()] )
except: # should be tighter
raise faults.BadValue()
register(Duration)
@ -733,28 +782,19 @@ class Email(WidgetMixin, proxyWidgets.Email):
layout += ' '
layout += X.buttonInForm('apply', 'applyButton')
return layout
def getModelHiddenLayout(self, slot, fields):
fieldName = slot.getFieldName()
fieldValue = slot.getValue() or ''
return X.array(
X.input(name = fieldName, type = 'hidden',
value = fieldValue),
)
register(Email)
class InputCheckBox(WidgetMixin, proxyWidgets.InputCheckBox):
def getHtmlViewValue(self, slot, fields, **keywords):
kind = slot.getKind()
value = kind.getModelValueFromFields(slot, fields)
value = slot.getValue()
return self.makeModelTitleFromValue(slot, fields, value)
def getHtmlFormValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
kind = slot.getKind()
value = kind.getModelValueFromFields(slot, fields)
value = slot.getValue() or 0
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
@ -790,6 +830,12 @@ class InputCheckBox(WidgetMixin, proxyWidgets.InputCheckBox):
if labels and labels.has_key(valueAsString):
return _(labels[valueAsString])
return None
def submit(self, slot, fields):
value = WidgetMixin.submit(self, slot, fields)
if value is None:
value = 0
return int(value)
register(InputCheckBox)
@ -896,6 +942,10 @@ class Link(WidgetMixin, proxyWidgets.Link):
X.input(name = urlFieldName, type = 'hidden',
value = urlFieldValue),
)
def submit(self, slot, fields):
return (slot.getFieldOption(fields, 'name', default = ''),
slot.getFieldOption(fields, 'url', default = '') )
register(Link)
@ -906,7 +956,6 @@ class Mapping(WidgetMixin, proxyWidgets.Mapping):
count = kind.getItemsCount(slot, fields)
layout = X.array()
fieldset = X.div(_class = 'fieldset')
# not X.fieldset because it's buggy on several proprietary browsers
layout += fieldset
if self.isInForm():
layout += X.input(name = countName, type = 'hidden', value = count)
@ -956,6 +1005,55 @@ class Mapping(WidgetMixin, proxyWidgets.Mapping):
slot.getPath(), str(valueSlot.getKind().__dict__)))
layout += valueWidget.getModelHiddenLayout(valueSlot, fields)
return layout
def submit(self, slot, fields):
count = slot.getKind().fieldsCountMin
try:
count = max(count,
int(slot.getFieldOption(fields, 'count', default = '0')))
except ValueError:
pass
value = {}
for i in range(count):
keySlot = slot.getKind().getItemKeySlot(slot, i)
try:
keyKind = keySlot.getKind()
keyValue = keySlot.getWidget().submit(keySlot, fields)
if keyValue is None:
continue
if type(keyValue) != keyKind.pythonStorageType:
keyValue = keyKind.convertValueFromOtherType(keyValue)
if keyKind.isEmptyModelValue(keySlot, keyValue):
continue
keyKind.checkModelValue(keySlot, keyValue)
except faults.BaseFault, f:
slot.getObject().setError(keySlot.getPath(), f)
itemSlot = slot.getKind().getItemKeyValueSlot(keySlot)
try:
itemKind = itemSlot.getKind()
itemValue = itemSlot.getWidget().submit(itemSlot, fields)
if itemValue is None and kind.deleteNullValues:
continue
if type(itemValue) != itemKind.pythonStorageType:
itemValue = itemKind.convertValueFromOtherType(itemValue)
if itemKind.isEmptyModelValue(itemSlot, itemValue) and \
kind.deleteNullValues:
continue
except faults.BaseFault, f:
slot.getObject().setError(itemSlot.getPath(), f)
value[keyValue] = itemValue
addButtonName = slot.getFieldOptionName('addButton')
if isButtonSelected(addButtonName, fields):
# TODO: fill with default value
count = count + 1
slot.setFieldOption(fields, 'count', str(count))
context.setVar('again', 1)
context.setVar('hideErrors', 1)
return value
register(Mapping)
@ -963,7 +1061,7 @@ class Multi(WidgetMixin, proxyWidgets.Multi):
def getHtmlViewValue(self, slot, fields, **keywords):
kind = slot.getKind()
layout = X.ul(_class = 'multi')
value = slot.getValue()
value = slot.getValue() or []
for i, v in zip(range(len(value)), value):
itemSlot = kind.getItemSlot(slot, i)
itemWidget = itemSlot.getWidget()
@ -978,6 +1076,8 @@ class Multi(WidgetMixin, proxyWidgets.Multi):
kind = slot.getKind()
countName = slot.getFieldOptionName('count')
count = kind.getItemsCount(slot, fields)
if slot.getValue():
count = max(count, len(slot.getValue()) )
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
@ -1007,7 +1107,12 @@ class Multi(WidgetMixin, proxyWidgets.Multi):
layout += X.buttonInForm('apply', 'applyButton')
return layout
def getModelHiddenLayout(self, slot, fields):
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
return X.array(
self.getModelHiddenLayout(slot, fields, children = 0),
self.getHtmlViewValue(slot, fields, **keywords) )
def getModelHiddenLayout(self, slot, fields, children = 1):
countName = slot.getFieldOptionName('count')
count = slot.getKind().fieldsCountMin
try:
@ -1018,17 +1123,19 @@ class Multi(WidgetMixin, proxyWidgets.Multi):
layout = X.array()
if count:
layout += X.input(name = countName, type = 'hidden', value = count)
for i in range(count):
itemSlot = slot.getKind().getItemSlot(slot, i)
itemWidget = itemSlot.getWidget()
if itemWidget is None:
raise Exception('Missing item widget for %s in %s' % (
slot.getPath(), str(itemSlot.getKind().__dict__)))
layout += itemWidget.getModelHiddenLayout(itemSlot, fields)
if children:
for i in range(count):
itemSlot = slot.getKind().getItemSlot(slot, i)
itemWidget = itemSlot.getWidget()
if itemWidget is None:
raise Exception('Missing item widget for %s in %s' % (
slot.getPath(), str(itemSlot.getKind().__dict__)))
layout += itemWidget.getModelHiddenLayout(itemSlot, fields)
return layout
def submit(self, slot, fields):
count = 1 # FIXME: was self.fieldsCountMin
kind = slot.getKind()
count = kind.fieldsCountMin
try:
count = max(count,
int(slot.getFieldOption(fields, 'count', default = '0')))
@ -1036,40 +1143,39 @@ class Multi(WidgetMixin, proxyWidgets.Multi):
pass
value = []
kind = slot.getKind()
for i in range(count):
itemSlot = kind.getItemSlot(slot, i)
itemWidget = itemSlot.getWidget()
itemKind = itemSlot.getKind()
try:
valueKind, itemValue = itemWidget.submit(itemSlot, fields)
if valueKind is not None:
itemValue = itemKind.convertValueFromOtherKind(
itemValue, valueKind)
else:
# nothing selected; nothing added
itemValue = itemWidget.submit(itemSlot, fields)
if itemValue is None:
# what if emptyValue != None ?
continue
if type(itemValue) != itemKind.pythonStorageType:
itemValue = itemKind.convertValueFromOtherType(itemValue)
if itemKind.isEmptyModelValue(itemSlot, itemValue):
continue
itemKind.checkModelValue(itemSlot, itemValue)
except faults.BaseFault, f:
itemSlot.getObject().setError(slot.getPath(), f)
fields['again'] = '1'
fields['error'] = '1'
context.setVar('again', 1)
context.setVar('error', 1)
continue
value.append(itemValue)
addButtonName = slot.getFieldOptionName('addButton')
if isButtonSelected(addButtonName, fields):
count = count + 1
slot.setFieldOption(fields, 'count', str(count))
fields['again'] = '1'
fields['hideErrors'] = '1'
return kinds.Sequence(), value
itemSlot = kind.getItemSlot(slot, count)
itemKind = itemSlot.getKind()
value.append(itemKind.getDefaultValue(itemSlot))
context.setVar('again', 1)
context.setVar('hideErrors', 1)
return value
register(Multi)
class MultiCheck(WidgetMixin, proxyWidgets.MultiCheck):
def getHtmlViewValue(self, slot, fields, **keywords):
kind = slot.getKind()
layout = X.ul()
@ -1103,22 +1209,22 @@ class MultiCheck(WidgetMixin, proxyWidgets.MultiCheck):
values = kind.itemKind.getValues(slot, fields)
for i in range(len(values)):
fieldName = slot.getFieldOptionName(values[i])
fieldValue = slot.getFieldOption(fields, values[i])
if fieldValue == 'on':
itemValue = slot.getFieldOption(fields, values[i])
if itemValue == 'on':
value.append(values[i])
return kinds.Sequence(), value
return value
register(MultiCheck)
class Path(WidgetMixin, proxyWidgets.Path):
def getHtmlViewValue(self, slot, fields, **keywords):
fieldValue = slot.getField(fields, default = '')
fieldValue = slot.getValue() or ''
return X.a(href = X.idUrl(object.id).add('path', fieldValue))(
fieldValue)
def getHtmlFormValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = slot.getField(fields, default = '')
fieldValue = slot.getValue() or ''
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
@ -1155,7 +1261,7 @@ register(PushButton)
class Select(WidgetMixin, proxyWidgets.Select):
def getHtmlViewValue(self, slot, fields, **keywords):
kind = slot.getKind()
value = kind.getModelValueFromFields(slot, fields)
value = slot.getValue() or ''
valueAsString = kind.getModelValueAsString(value)
labels = self.getLabels(slot, fields)
if labels.has_key(valueAsString):
@ -1168,8 +1274,18 @@ class Select(WidgetMixin, proxyWidgets.Select):
def getHtmlFormValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
kind = slot.getKind()
value = kind.getModelValueFromFields(slot, fields)
valueAsString = kind.getModelValueAsString(value)
try:
value = slot.getValue() or ''
except IndexError:
value = None
if type(value) is types.StringType:
valueAsString = value
else:
try:
valueAsString = kind.convertValueToOtherType(value, types.StringType)
except: # happens with class_ instance
valueAsString = ''
if hasattr(kind, 'sortLabels') and kind.sortLabels:
values = kind.getSortedValues(slot, fields)
@ -1187,7 +1303,7 @@ class Select(WidgetMixin, proxyWidgets.Select):
selectAttributes['name'] = fieldName
select = X.select(**selectAttributes)
itemsCount = len(values)
if not value in values:
if not valueAsString in [x or '' for x in values]:
if labels.has_key(valueAsString):
noneLabel = _(labels[valueAsString])
else:
@ -1219,7 +1335,7 @@ class Select(WidgetMixin, proxyWidgets.Select):
for itemValue in groupValues:
optionAttributes = {}
itemValueAsString = kind.getModelValueAsString(itemValue)
if itemValue == value:
if itemValue == valueAsString:
optionAttributes['selected'] = 'selected'
if labels.has_key(itemValueAsString):
label = _(labels[itemValueAsString])
@ -1289,8 +1405,8 @@ class SelectId(WidgetMixin, proxyWidgets.SelectId):
layout += self.getModelErrorLayout(slot, fields)
layout += self.getModelHelpLayout(slot, fields)
kind = slot.getKind()
serverRoles = kind.getServerRoles()
if not serverRoles:
serverRoles = kind.getServerRoles(slot)
if serverRoles is None:
serverRoles = context.getVar('knownRoles')
serverRoles = serverRoles[:]
serverRoles.sort()
@ -1353,10 +1469,8 @@ class TextArea(WidgetMixin, proxyWidgets.TextArea):
**textareaAttributes)(fieldValue)
else:
virtualHost = context.getVar('virtualHost')
sectionLevel = 2
if virtualHost:
sectionLevel = int(webTools.getConfig('BaseSectionLevel', '2'))
format = slot.getKind().textFormat
sectionLevel = context.getVar('sectionLevel') + 1
format = slot.getKind().getTextFormat(slot)
inline = context.getVar('inline', default = 0)
if format == 'docbook':
formattedText = parsers.makeHtmlFromDocBook(
@ -1387,7 +1501,7 @@ class TextArea(WidgetMixin, proxyWidgets.TextArea):
return layout
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
fieldValue = slot.getField(fields, default = '')
fieldValue = slot.getValue() or ''
layout = X.array(self.getModelHiddenLayout(slot, fields))
if self.viewInTextArea:
textareaAttributes = self.getTextAreaAttributes()
@ -1395,11 +1509,8 @@ class TextArea(WidgetMixin, proxyWidgets.TextArea):
**textareaAttributes)(fieldValue)
return layout
else:
virtualHost = context.getVar('virtualHost')
sectionLevel = 2
if virtualHost:
sectionLevel = int(webTools.getConfig('BaseSectionLevel', '2'))
format = slot.getKind().textFormat
sectionLevel = context.getVar('sectionLevel') + 1
format = slot.getKind().getTextFormat(slot)
inline = context.getVar('inline', default = 0)
if format == 'docbook':
formattedText = parsers.makeHtmlFromDocBook(
@ -1441,7 +1552,7 @@ class TextArea(WidgetMixin, proxyWidgets.TextArea):
def getHtmlFormValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = slot.getField(fields, default = '')
fieldValue = slot.getValue() or ''
textareaAttributes = self.getTextAreaAttributes()
@ -1460,11 +1571,14 @@ class TextArea(WidgetMixin, proxyWidgets.TextArea):
buttonsBar += X.buttonInForm('apply', 'applyButton')
if self.preview and fieldValue:
format = slot.getKind().textFormat
format = slot.getKind().getTextFormat(slot)
if format == 'docbook':
formattedText = parsers.makeHtmlFromDocBook(fieldValue)
elif format == 'html':
formattedText = parsers.makeHtmlFromHtml(fieldValue)
if not slot.getObject().getError(slot.getPath()):
formattedText = parsers.makeHtmlFromHtml(fieldValue)
else:
formattedText = '<strong>error in HTML</strong>'
elif format == 'text':
formattedText = parsers.makeHtmlFromPreformattedText(
fieldValue)
@ -1479,8 +1593,10 @@ class TextArea(WidgetMixin, proxyWidgets.TextArea):
formattedText = replaceSpecialTags(formattedText)
preferences = context.getVar('preferences')
if (not preferences or preferences.spellcheckEntries) and \
fields.has_key('language'):
formattedText = spellcheck(formattedText, fields['language'])
slot.getObject().hasSlotName('language'):
languageSlot = slot.getObject().getSlot('language')
formattedText = spellcheck(formattedText,
languageSlot.getValue())
if formattedText:
layout += X.div(_class = 'preview')(X.asIs(formattedText))
@ -1527,7 +1643,7 @@ class UploadFile(WidgetMixin, proxyWidgets.UploadFile):
typeSlot = slot.getContainer().getSlot(
slot.name + 'Type', parentSlot = slot.parent)
if isTypeOfMimeType(typeSlot.getField(fields, default = ''), 'image'):
if isTypeOfMimeType(typeSlot.getValue() or '', 'image'):
uri = X.idUrl(object.id, 'thumbnail')
if slot.parent is not None:
uri.add('path', slot.parent.getPath())
@ -1547,62 +1663,95 @@ class UploadFile(WidgetMixin, proxyWidgets.UploadFile):
return ''
def getHtmlReadOnlyValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = slot.getField(fields, default = '')
session = context.getVar('session')
if session is not None:
session['field_' + fieldName] = base64.encodestring(fieldValue)
session['isDirty'] = 1
return X.array(
self.getModelHiddenLayout(slot, fields),
self.getRepresentation(slot, fields, **keywords) )
def getModelHiddenLayout(self, slot, fields):
value = slot.getValue()
typeSlot = slot.getContainer().getSlot(
slot.name + 'Type', parentSlot = slot.parent)
fileName = self.fileName or ''
data = {
'data': value,
'type': typeSlot.getValue() or '',
'fileName': fileName
}
if context.getVar('session') is None:
# TODO: create session
pass
sessionsProxy = getProxyForServerRole('sessions')
self.dataToken = sessionsProxy.addTemporaryData(data)
return X.input(name = slot.getFieldOptionName('dataToken'),
type = 'hidden', value = self.dataToken)
def getHtmlFormValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = slot.getField(fields, default = '')
fieldValue = slot.getValue() or ''
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
layout += self.getModelHelpLayout(slot, fields)
session = context.getVar('session')
if session is not None:
session['field_' + fieldName] = base64.encodestring(fieldValue)
session['isDirty'] = 1
layout += X.input(name = '%s|session' % fieldName,
type = 'hidden', value = 1)
layout += self.getModelHiddenLayout(slot, fields)
representation = self.getRepresentation(slot, fields, **keywords)
if representation:
layout += representation
layout += X.br()
layout += X.input(name = '%s_field' % fieldName, type = 'file')
layout += X.input(name = fieldName, type = 'file')
return layout
def getRepresentation(self, slot, fields, **keywords):
typeSlot = slot.getContainer().getSlot(
slot.name + 'Type', parentSlot = slot.parent)
if not isTypeOfMimeType(
typeSlot.getField(fields, default = ''), 'image'):
if not isTypeOfMimeType(typeSlot.getValue() or '', 'image'):
return ''
typeSlot = slot.getContainer().getSlot(
slot.name + 'Type', parentSlot = slot.parent)
object = slot.getObject()
fieldName = slot.getFieldName()
uri = X.idUrl(object.id, 'imageEdit')
if slot.parent is not None:
uri.add('path', slot.parent.getPath())
uri.add('%s|session' % fieldName, 1)
uri.addKeywords(keywords)
uri.add('dataToken', self.dataToken)
return X.img(src = uri)
def submit(self, slot, fields):
value = slot.getField(fields)
upload = commonTools.newThing('other', 'Upload')
dataToken = slot.getFieldOption(fields, 'dataToken')
sessionsProxy = getProxyForServerRole('sessions')
if value.value:
upload.data = value.value
upload.dataFileName = value.filename
upload.dataType = value.type
else:
data = sessionsProxy.getTemporaryData(dataToken)
if not data:
return None
upload.data = data['data']
upload.dataFileName = data['fileName']
upload.dataType = data['type']
# UploadFiles use Upload widget but not Upload kind
# (and it wants information about type and filename)
#
# This line (+ more in UploadFilesWeb.py (submitFields))
# is there while waiting for UploadFiles conversion
# to Upload kind.
context.setVar('UploadFilesXXX', upload)
sessionsProxy.delTemporaryData(dataToken)
return upload
register(UploadFile)
class Url(WidgetMixin, proxyWidgets.Url):
def getHtmlViewValue(self, slot, fields, **keywords):
fieldValue = slot.getField(fields, default = '')
fieldValue = slot.getValue() or ''
if fieldValue:
if fieldValue.startswith('http://'):
href = fieldValue
@ -1614,7 +1763,7 @@ class Url(WidgetMixin, proxyWidgets.Url):
def getHtmlFormValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = str(slot.getField(fields, default = ''))
fieldValue = slot.getValue() or ''
layout = X.array()
layout += self.getModelErrorLayout(slot, fields)
@ -1638,15 +1787,6 @@ class Url(WidgetMixin, proxyWidgets.Url):
layout += ' '
layout += X.buttonInForm('apply', 'applyButton')
return layout
def getModelHiddenLayout(self, slot, fields):
fieldName = slot.getFieldName()
fieldValue = slot.getField(fields, default = '')
return X.array(
X.input(name = fieldName, type = 'hidden',
value = fieldValue),
)
register(Url)
@ -1656,7 +1796,7 @@ class XSelect(Select, proxyWidgets.XSelect):
def getHtmlValue(self, slot, fields, **keywords):
fieldName = slot.getFieldName()
fieldValue = slot.getField(fields, default = '')
fieldValue = slot.getValue()
if fieldValue is None:
fieldValue = ''
else:
@ -1788,11 +1928,7 @@ class XSelect(Select, proxyWidgets.XSelect):
def getModelHiddenLayout(self, slot, fields):
fieldName = slot.getFieldName()
otherFieldName = slot.getFieldOptionName('other')
fieldValue = slot.getField(fields, default = '')
otherFieldValue = slot.getFieldOption(fields, 'other', default = '')
if otherFieldValue:
return X.input(name = otherFieldName, type = 'hidden',
value = otherFieldValue)
fieldValue = slot.getValue() or ''
return X.input(name = fieldName, type = 'hidden', value = fieldValue)
def makeModelTitleFromValue(self, slot, fields, value):
@ -1812,5 +1948,11 @@ class XSelect(Select, proxyWidgets.XSelect):
if labels and labels.has_key(valueAsString):
return _(labels[valueAsString])
return valueAsString
def submit(self, slot, fields):
otherFieldValue = slot.getFieldOption(fields, 'other', default = '')
if otherFieldValue:
return otherFieldValue
return WidgetMixin.submit(self, slot, fields)
register(XSelect)

View File

@ -69,7 +69,7 @@ class BuildCase01_generalPublicGroup(unittest.TestCase):
"""Build the general public group."""
group = groups.GroupAll()
group.acceptedRoles = ['people']
group.acceptedRoles = ['people', 'ldappeople']
group.language = 'en'
group.name = N_('General Public')
## group.itemIds = [system.generalPublicId]
@ -78,6 +78,18 @@ class BuildCase01_generalPublicGroup(unittest.TestCase):
commonTools.extractLocalId(groupId),
commonTools.extractLocalId(system.generalPublicId))
def build02_loggedUserGroup(self):
"""Build the logged users group."""
group = groups.GroupRole()
group.acceptedRoles = [ 'people', 'ldappeople' ]
group.language = 'en'
group.name = N_('Logged Users')
groupId = groupsProxy.addObject(group)
self.failUnlessEqual(
commonTools.extractLocalId(groupId),
commonTools.extractLocalId(system.loggedUsersGroupId))
buildLoader = unittest.TestLoader()
buildLoader.testMethodPrefix = 'build'

View File

@ -89,11 +89,11 @@ h2.title {
font-size: 120%;
}
h3.author {
li.authors {
font-size: 90%;
}
p.pubdate {
li.edition-time {
font-size: 60%;
}

View File

@ -119,11 +119,11 @@ h2.title {
font-size: 120%;
}
h3.author {
li.authors {
font-size: 90%;
}
p.pubdate {
li.edition-time {
font-size: 60%;
}

View File

@ -68,8 +68,8 @@ p {
text-align: justify;
}
h3.author { display: none; }
p.pubdate { display: none; }
li.authors { display: none; }
li.edition-time{ display: none; }
h2.title {
color: #F18B1D;

View File

@ -80,7 +80,7 @@ h2.title {
text-align: center;
}
h3.author {
li.authors {
font-size: xx-small;
}

View File

@ -229,10 +229,6 @@ body>#menu {width:234px;}
display: inline;
}
.author {
padding-bottom: 6px;
}
#clock {
background-image: url("../img/ikon_clock.png");
background-repeat: no-repeat;

View File

@ -224,10 +224,6 @@ body>#menu {width:190px;}
display: inline;
}
.author {
padding-bottom: 6px;
}
#clock {
background-image: url("../img/ikon_clock.png");
background-repeat: no-repeat;

View File

@ -211,10 +211,6 @@ body>#header {height:14px;}
display: inline;
}
.author {
padding-bottom: 6px;
}
#clock {
background-image: url("../img/ikon_clock.png");
background-repeat: no-repeat;

View File

@ -37,14 +37,6 @@ p img {
margin: 0;
}
hr {
clear: both;
height: 1px;
color: #316700;
}
h1, h2, h3, h4, h5, h6 {
color: black;
clear: left;
@ -622,7 +614,7 @@ div.error-message {
.odd {
}
div#main-content h3.author {
div#main-content li.authors {
margin: 0;
padding-top: 5px;
font-size: 80%;
@ -630,7 +622,7 @@ div#main-content h3.author {
margin-left: 1em;
}
div#main-content p.pubdate {
div#main-content li.edition-time {
font-size: 70%;
margin-left: 1em;
}

View File

@ -90,11 +90,11 @@ h2.title {
font-size: 120%;
}
h3.author {
li.authors {
font-size: 90%;
}
p.pubdate {
li.edition-time {
font-size: 60%;
}

View File

@ -129,11 +129,11 @@ h2.title {
font-size: 120%;
}
h3.author {
li.authors {
font-size: 90%;
}
p.pubdate {
li.edition-time {
font-size: 60%;
}

View File

@ -54,6 +54,10 @@ h1, h2, h3, h4 {
font-weight: normal;
}
h1 {
font-weight: bold;
}
.spacer {
clear: both;
}
@ -231,3 +235,24 @@ table.calendar-month-full th, table.calendar-week-full th {
background-color: #f0f0f0;
}
hr {
clear: both;
height: 1px;
color: #444;
background-color: #444;
border: 0;
}
span.comment-no {
display: block;
float: left;
font-size: 200%;
padding-right: 0.5em;
font-style: italic;
color: #888;
}
div.comment h2, div.comment h3 {
clear: none;
}

View File

@ -9,7 +9,8 @@
<div metal:fill-slot="main">
<div class="spacer">&nbsp;</div>
<div id="contact-infos" tal:content="structure GlasnostObject('/articles/3').getFormattedBody()"
<div tal:replace="structure GlasnostObject('/articles/3').getFormattedBody()"
tal:on-error="nothing">
Présentation de Glasnost
</div>

View File

@ -34,12 +34,6 @@ p img {
}
hr {
clear: both;
height: 1px;
color: #8cacbb;
}
h1, h2, h3, h4, h5, h6 {
color: black;
clear: left;
@ -585,17 +579,19 @@ div.error-message {
.odd {
}
div#main-content h3.author {
margin: 0;
padding-top: 5px;
font-size: 80%;
border-bottom: 0;
margin-left: 1em;
ul.article-meta {
margin-top: -1em;
list-style: none;
}
div#main-content p.pubdate {
ul.article-meta li.authors {
margin: 0;
font-size: 80%;
border-bottom: 0;
}
ul.article-meta li.edition-time {
font-size: 70%;
margin-left: 1em;
}
div#main-content h2 {

View File

@ -57,7 +57,6 @@ h1#header {
div#content {
margin: 4em 14em 0px 50px;
text-align: justify;
}
div#content h1 {
@ -72,6 +71,7 @@ div#content h2 {
/*margin-left: -30px;*/
margin-left: 0.5em;
margin-right: 10%;
margin-bottom: 0;
color: #33517f;
border-bottom: 1px solid #33517f;
font-weight: normal;
@ -82,18 +82,27 @@ div#content h2:first-letter {
/*color: #90abdb;*/
}
div.titlepage {
div#content p {
margin: 0.5em 0;
text-align: justify;
}
ul.article-meta {
border: 1px solid #33517f;
border-top: none;
float: right;
background: #7297ce url('/images/border-top.png') top left repeat-x;
margin: -5px 1em 1em 1em;
font-size: 80%;
padding: 0;
}
div.titlepage .author, div.titlepage p {
margin: 0 1em;
font-size: 100%;
ul.article-meta li {
text-align: center;
max-width: 13em;
margin: 0 0.5em;
padding: 0;
list-style: none;
}
a:link {
@ -149,7 +158,9 @@ div.row ul {
div.buttons-bar {
margin-top: 1em;
width: 130%;
clear: both;
text-align: left;
}
div.buttons-bar .button {
@ -236,3 +247,15 @@ div.diff-error {
margin: 0.5em 0 0 2em;
}
pre {
border: 1px solid #44618f;
background: #a0bbfb;
padding: 0 0.5em;
}
div.comment span.comment-no {
float: left;
font-size: 200%;
padding-right: 0.5em;
}