328 lines
11 KiB
Python
328 lines
11 KiB
Python
# -*- coding: iso-8859-15 -*-
|
|
|
|
|
|
# Glasnost
|
|
# By: Odile Bénassy <obenassy@entrouvert.com>
|
|
# Romain Chantereau <rchantereau@entrouvert.com>
|
|
# Nicolas Clapiès <nclapies@easter-eggs.org>
|
|
# Pierre-Antoine Dejace <padejace@entrouvert.be>
|
|
# Thierry Dulieu <tdulieu@easter-eggs.com>
|
|
# Florent Monnier <monnier@codelutin.com>
|
|
# Cédric Musso <cmusso@easter-eggs.org>
|
|
# Frédéric Péters <fpeters@entrouvert.be>
|
|
# Benjamin Poussin <poussin@codelutin.com>
|
|
# Emmanuel Raviart <eraviart@entrouvert.com>
|
|
# Sébastien Régnier <regnier@codelutin.com>
|
|
# Emmanuel Saracco <esaracco@easter-eggs.com>
|
|
#
|
|
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
|
|
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
|
|
# Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
|
|
# Emmanuel Saracco & Théridion
|
|
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
|
|
# Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
|
|
# Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
|
|
# Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
|
|
# Régnier, Emmanuel Saracco, Théridion & Vecam
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
from __future__ import nested_scopes
|
|
|
|
__doc__ = """Glasnost Forums Web"""
|
|
|
|
__version__ = '$Revision$'[11:-2]
|
|
|
|
|
|
import glasnost.common.context as context
|
|
import glasnost.common.faults as faults
|
|
import glasnost.common.slots as slots
|
|
import glasnost.common.tools_new as commonTools
|
|
|
|
from glasnost.proxy.ForumsProxy import *
|
|
|
|
from ObjectsWeb import register, AdminMixin, ObjectWebMixin, ObjectsWebMixin
|
|
from tools import *
|
|
|
|
|
|
class AdminForums(AdminMixin, AdminForums):
|
|
pass
|
|
register(AdminForums)
|
|
|
|
|
|
class Forum(ObjectWebMixin, Forum):
|
|
description_kind_textFormat = 'spip'
|
|
description_kind_widget_fieldLabel = N_('Description')
|
|
description_kind_widget_preview = 1
|
|
description_kind_widgetName = 'TextArea'
|
|
|
|
title_kind_widget_fieldLabel = N_('Title')
|
|
title_kind_widgetName = 'InputText'
|
|
|
|
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()
|
|
layout += comment.getErrorLayout(error, 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
|
|
|