# -*- 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.


__doc__ = """Glasnost Articles Web"""

__version__ = '$Revision$'[11:-2]


import copy
import re

import glasnost.common.context as context
import glasnost.common.faults as faults
import glasnost.common.slots as slots

from glasnost.proxy.ArticlesProxy import *

from ObjectsWeb import register, AdminMixin, ObjectWebMixin, ObjectsWebMixin, \
        CommentableObjectMixin
from tools import *


class AdminArticles(AdminMixin, AdminArticles):
    pass
register(AdminArticles)


class Article(ObjectWebMixin, Article):
    editionTime_kind_stateInEditMode = 'hidden'
    editionTime_kind_widget_fieldLabel = N_('Edition Time')
    editionTime_kind_widgetName = 'InputText'

    format_kind_defaultValue = 'spip'
    format_kind_widget_fieldLabel = N_('Format')
    format_kind_widget_labels = {
        'html': N_('HTML'),
        'spip': N_('SPIP'),
        'rst': N_('reStructured Text'),
        }
    format_kind_widgetName = 'Select'

    lastEditorId_kind_stateInEditMode = 'read-only'
    lastEditorId_kind_widget_fieldLabel = N_('Last Editor')
    lastEditorId_kind_widgetName = 'SelectId'

    title_kind_widget_fieldLabel = N_('Title')
    title_kind_widget_size = 40
    title_kind_widgetName = 'InputText'

    def getFormattedBody(self, translate = 0):
        # TODO: don't duplicate from widgets.
        fieldValue = self.body
        if translate:
            slot = self.getSlot('body')
            translationsProxy = getProxyForServerRole('translations')
            if translationsProxy:
                fieldValue, destinationLanguage, state = \
                        translationsProxy.getTranslationInfos(
                                fieldValue, self.id, slot.getPath(),
                                self.getLanguage(),
                                context.getVar('readLanguages'))
                if state not in ('translated', 'untranslatable'):
                    fieldValue = self.body
        virtualHost = context.getVar('virtualHost')
        sectionLevel = context.getVar('sectionLevel')+1
        if self.format == 'docbook':
            formattedText = parsers.makeHtmlFromDocBook(fieldValue)
        elif self.format == 'html':
            formattedText = parsers.makeHtmlFromHtml(fieldValue)
        elif self.format == 'text':
            formattedText = parsers.makeHtmlFromPreformattedText(fieldValue)
        elif self.format == 'rst':
            formattedText = parsers.makeHtmlFromReStructuredText(fieldValue,
                    sectionLevel = sectionLevel)
        else:
            formattedText = parsers.makeHtmlFromSpip(fieldValue,
                    sectionLevel = sectionLevel)

        return replaceSpecialTags(formattedText)

    def getViewLayout(self, fields, parentSlot = None):
        layout = X.array()
        if self.title:
            translationsProxy = getProxyForServerRole('translations')
            if translationsProxy:
                title = translationsProxy.getTranslation(
                    self.title, self.getId(), 'self.title',
                    self.getLanguage(), context.getVar('readLanguages'))
            else:
                title = self.title
        else:
            title = ''
        if parentSlot and parentSlot.getLabel() == 'Root':
            context.setVar('pageTitle', title)

        sectionLevel = context.getVar('sectionLevel')
        titleTag = getattr(X, 'h%s' % (sectionLevel))
        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()

        slotsLayout = ObjectWebMixin.getViewLayout(
                            self, fields, parentSlot = parentSlot)
        if slotsLayout:
            layout += X.div(_class = 'slots')(slotsLayout)
        return layout

    def getViewLayoutSlotNames(self, fields, parentSlot = None):
        slotNames = ObjectWebMixin.getViewLayoutSlotNames(
            self, fields, parentSlot = parentSlot)
        slotNames = slotNames[:]
        if 'body' in slotNames:
            slotNames.remove('body')
        userToken = context.getVar('userToken', default = '')
        if context.getVar('useCompactLayout', default = 0) or \
                not self.getWeb().canModifyObject(self.id):
            for slotName in (
                    'authorsSet', 'creationTime', 'editionTime', 'format',
                    'lastEditorId', 'modificationTime', 'readersSet', 'title',
                    'writersSet'):
                if slotName in slotNames:
                    slotNames.remove(slotName)
        return slotNames
register(Article)


class ArticlesWeb(ObjectsWebMixin, CommentableObjectMixin, ArticlesProxy):
        
    def all(self):
        return ObjectsWebMixin.viewAll(self, slotNames = ['editionTime'])
    all.isPublicForWeb = 1

    def docBook(self, id):
        if not self.hasObject(id):
            return pageNotFound()
        article = self.getObject(id)
        title = getProxyForServerRole('translations').getTranslation(
            article.getTitle(), article.getId(), 'self.title',
            article.getLanguage(), context.getVar('readLanguages'))
        body = getProxyForServerRole('translations').getTranslation(
            article.getBody(), article.getId(), 'self.body',
            article.getLanguage(), context.getVar('readLanguages'))
        docBook = makeDocBookFromSpip(body, title = title)
        html =  parsers.makeHtmlFromDocBook(docBook)
        html = replaceSpecialTags(html)

        label = article.getLabelTranslated(
            context.getVar('readLanguages'))

        layout = X.array()
        layout += X.asIs(html)
        return writePageLayout(layout, _('DocBook - %s') % label)
    docBook.isPublicForWeb = 1

    def docBookSource(self, id):
        if not self.hasObject(id):
            return pageNotFound()
        article = self.getObject(id)
        title = getProxyForServerRole('translations').getTranslation(
            article.getTitle(), article.getId(), 'self.title',
            article.getLanguage(), context.getVar('readLanguages'))
        body = getProxyForServerRole('translations').getTranslation(
            article.getBody(), article.getId(), 'self.body',
            article.getLanguage(), context.getVar('readLanguages'))
        docBook = makeDocBookFromSpip(body, title = title)
        docBook = replaceSpecialTags(docBook)

        label = article.getLabelTranslated(
            context.getVar('readLanguages'))

        layout = X.array()
        layout += X.pre(docBook)
        return writePageLayout(layout, _('DocBook Source - %s') % label)
    docBookSource.isPublicForWeb = 1

    def getViewAllNavigationButtonsBarLayoutSomeTimes(self):
        layout = X.array()
        layout += X.buttonStandalone('all-articles', X.actionUrl('all'))
        layout += ObjectsWebMixin.getViewAllNavigationButtonsBarLayout(self)
        return layout

    def getViewNavigationButtonsBarLayout(self, object, fields):
        layout = X.array()
        defaults = ObjectsWebMixin.getViewNavigationButtonsBarLayout(
                self, object, fields)
        if defaults:
            layout += defaults
        userToken = context.getVar('userToken')
        if userToken and object.format and object.format != 'text':
            layout += X.buttonStandalone(
                    'source', X.idUrl(object.id, 'source'))
        if layout:
            return layout
        else:
            return None

    def source(self, id):
        if not self.hasObject(id):
            return pageNotFound()
        article = self.getObject(id)
        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(body)
        return writePageLayout(layout, _('Source - %s') % label)
    source.isPublicForWeb = 1

    def viewAll(self):
        context.push(_level = 'viewAll',
                     defaultDispatcherId = context.getVar('dispatcherId'))
        try:
            if not self.canGetObjects():
                return accessForbidden()
            isAdmin = self.isAdmin()
            userId = context.getVar('userId', default = '')
            if userId:
                userSet = [userId]
            else:
                userSet = None

            layout = X.array()
            requiredSlotNames = ['editionTime', 'title']
            displayedSlotNames = ['editionTime']

            if userSet:
                lastArticles = self.getLastObjects(
                    10, None, None, userSet, requiredSlotNames)
                layout += self.getObjectsSectionLayout(
                    lastArticles,
                    _("""Your last articles"""),
                    displayedSlotNames)

            lastArticles = self.getLastObjects(
                10, None, userSet, None, requiredSlotNames)
            layout += self.getObjectsSectionLayout(
                lastArticles,
                _("""The last articles"""),
                displayedSlotNames)

            self.getViewAllNavigationButtonsBarLayout = \
                self.getViewAllNavigationButtonsBarLayoutSomeTimes
            layout += self.getViewAllButtonsBarLayout()
            del self.getViewAllNavigationButtonsBarLayout
        finally:
            context.pull(_level = 'viewAll')
        return writePageLayout(layout, _('Articles'))
    viewAll.isPublicForWeb = 1

