## $Id: browser.py 13066 2015-06-16 14:48:55Z henrik $ ## ## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann ## 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 ## """UI components for documents offered for download by the company. """ import sys import grok import pytz from urllib import urlencode from datetime import datetime from hurry.workflow.interfaces import ( IWorkflowInfo, IWorkflowState, InvalidTransitionError) from zope.event import notify from zope.i18n import translate from zope.catalog.interfaces import ICatalog from zope.component import queryUtility, getUtility, createObject from zope.schema.interfaces import ConstraintNotSatisfied, RequiredMissing from zope.formlib.textwidgets import BytesDisplayWidget from zope.security import checkPermission from waeup.ikoba.utils.helpers import html2dict, rest2dict from waeup.ikoba.interfaces import MessageFactory as _ from waeup.ikoba.interfaces import ( IContactForm, IObjectHistory, IIkobaObject, IIkobaUtils, PUBLISHED) from waeup.ikoba.browser.layout import ( IkobaPage, IkobaEditFormPage, IkobaAddFormPage, IkobaDisplayFormPage, NullValidator, jsaction, action, UtilityView) from waeup.ikoba.widgets.datewidget import ( FriendlyDateWidget, FriendlyDateDisplayWidget, FriendlyDatetimeDisplayWidget) from waeup.ikoba.browser.breadcrumbs import Breadcrumb from waeup.ikoba.browser.pages import ( delSubobjects, add_local_role, del_local_roles, msave, LocalRoleAssignmentUtilityView) from waeup.ikoba.documents.interfaces import ( IDocumentsContainer, IPublicDocument, IHTMLDocument, IRESTDocument, IDocumentsUtils) grok.context(IIkobaObject) # Make IKofaObject the default context grok.templatedir('browser_templates') class DocumentsBreadcrumb(Breadcrumb): """A breadcrumb for the customers container. """ grok.context(IDocumentsContainer) title = _('Documents') class DocumentBreadcrumb(Breadcrumb): """A breadcrumb for the customer container. """ grok.context(IPublicDocument) def title(self): return self.context.title class DocumentsContainerPage(IkobaDisplayFormPage): """The standard view for document containers. """ grok.context(IDocumentsContainer) grok.name('index') grok.require('waeup.viewDocuments') grok.template('containerpage') pnav = 2 label = _('Documents') class DocumentsContainerManageFormPage(IkobaEditFormPage, LocalRoleAssignmentUtilityView): """The manage page for customer containers. """ grok.context(IDocumentsContainer) grok.name('manage') grok.require('waeup.manageDocuments') grok.template('containermanagepage') pnav = 2 label = _('Manage document section') @action(_('Add document'), validator=NullValidator, style='primary') def addSubunit(self, **data): self.redirect(self.url(self.context, 'adddoc')) return @jsaction(_('Remove selected documents')) def delDocuments(self, **data): delSubobjects(self, redirect='manage', tab='2') return @action(_('Cancel'), validator=NullValidator) def cancel(self, **data): self.redirect(self.url(self.context)) return class DocumentAddFormPage(IkobaAddFormPage): """Add-form to add a customer. """ grok.context(IDocumentsContainer) grok.require('waeup.manageDocuments') grok.name('adddoc') grok.template('documentaddform') label = _('Add document') pnav = 2 form_fields = grok.AutoFields(IPublicDocument) @property def selectable_doctypes(self): doctypes = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT return sorted(doctypes.items()) @action(_('Add document'), style='primary') def createDocument(self, **data): form = self.request.form doctype = form.get('doctype', None) # Here we can create various instances of PublicDocument derived # classes depending on the doctype parameter given in form. document = createObject('waeup.%s' % doctype) self.applyData(document, **data) try: self.context.addDocument(document) except KeyError: self.flash(_('The id chosen already exists.'), type='danger') return doctype = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT[doctype] self.flash(_('${a} added.', mapping = {'a': doctype})) ob_class = self.__implemented__.__name__.replace('waeup.ikoba.','') self.context.__parent__.logger.info( '%s - added: %s %s' % (ob_class, doctype, document.document_id)) self.redirect(self.url(self.context) + '/%s/manage' % document.document_id) return @action(_('Cancel'), validator=NullValidator) def cancel(self, **data): self.redirect(self.url(self.context)) class DocumentDisplayFormPage(IkobaDisplayFormPage): """ Page to display document data """ grok.context(IPublicDocument) grok.name('index') grok.require('waeup.viewDocuments') grok.template('documentpage') pnav = 2 @property def form_fields(self): return grok.AutoFields(self.context.form_fields_interface) @property def label(self): return self.context.title class HTMLDocumentDisplayFormPage(DocumentDisplayFormPage): """ Page to display html document data """ grok.context(IHTMLDocument) grok.template('htmldocumentpage') @property def form_fields(self): return grok.AutoFields(self.context.form_fields_interface).omit( 'html_dict', 'html_multilingual') @property def html(self): lang = self.request.cookies.get('ikoba.language') html = self.context.html_dict.get(lang,'') if html =='': portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE html = self.context.html_dict.get(portal_language,'') return html class HTMLDocumentDisplayContentPage(IkobaPage): """ Page to display the html content of document """ grok.context(IHTMLDocument) grok.name('display') grok.template('htmldisplaypage') grok.require('waeup.Public') @property def label(self): return self.context.title def update(self): if self.context.state != PUBLISHED: self.flash(_('The document requested has not yet been published.'), type="warning") self.redirect(self.application_url()) super(HTMLDocumentDisplayContentPage, self).update() return @property def content(self): lang = self.request.cookies.get('ikoba.language') html = self.context.html_dict.get(lang,'') if html =='': portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE html = self.context.html_dict.get(portal_language,'') return html class RESTDocumentDisplayFormPage(HTMLDocumentDisplayFormPage): """ Page to display html document data """ grok.context(IRESTDocument) @property def form_fields(self): return grok.AutoFields(self.context.form_fields_interface).omit( 'html_dict', 'rest_multilingual') class RESTDocumentDisplayContentPage(HTMLDocumentDisplayContentPage): """ Page to display the html content of document """ grok.context(IRESTDocument) label = None class DocumentManageFormPage(IkobaEditFormPage, LocalRoleAssignmentUtilityView): """ View to manage document data """ grok.context(IPublicDocument) grok.name('manage') grok.require('waeup.manageDocuments') grok.template('documentmanagepage') pnav = 2 taboneactions = [_('Save'),_('Cancel')] tabthreeactions1 = [_('Remove selected local roles')] tabthreeactions2 = [_('Add local role')] deletion_warning = _('Are you sure?') @property def form_fields(self): return grok.AutoFields( self.context.form_fields_interface).omit('document_id') def label(self): return _('Manage document ') + self.context.document_id @action(_('Save'), style='primary') def save(self, **data): return msave(self, **data) @action(_('Cancel'), validator=NullValidator) def cancel(self, **data): self.redirect(self.url(self.context)) return @action(_('Add local role'), validator=NullValidator) def addLocalRole(self, **data): return add_local_role(self,2,**data) @action(_('Remove selected local roles')) def delLocalRoles(self, **data): return del_local_roles(self,2,**data) class HTMLDocumentManageFormPage(DocumentManageFormPage): """ View to manage htmldocument data """ grok.context(IHTMLDocument) grok.template('htmldocumentmanagepage') @action(_('Save'), style='primary') def save(self, **data): msave(self, **data) html_multilingual = getattr(self.context, 'html_multilingual', None) portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE self.context.html_dict = html2dict(html_multilingual, portal_language) return class RESTDocumentManageFormPage(DocumentManageFormPage): """ View to manage restdocument data """ grok.context(IRESTDocument) grok.template('htmldocumentmanagepage') @action(_('Save'), style='primary') def save(self, **data): msave(self, **data) html_multilingual = getattr(self.context, 'rest_multilingual', None) portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE self.context.html_dict = rest2dict(html_multilingual, portal_language) return class DocumentTriggerTransitionFormPage(IkobaEditFormPage): """ View to trigger public document transitions """ grok.context(IPublicDocument) grok.name('trigtrans') grok.require('waeup.triggerTransition') grok.template('trigtrans') label = _('Trigger document transition') pnav = 2 def update(self): return super(IkobaEditFormPage, self).update() def getTransitions(self): """Return a list of dicts of allowed transition ids and titles. Each list entry provides keys ``name`` and ``title`` for internal name and (human readable) title of a single transition. """ wf_info = IWorkflowInfo(self.context) allowed_transitions = [t for t in wf_info.getManualTransitions()] return [dict(name='', title=_('No transition'))] +[ dict(name=x, title=y) for x, y in allowed_transitions] @action(_('Apply now'), style='primary') def apply(self, **data): form = self.request.form if 'transition' in form and form['transition']: transition_id = form['transition'] wf_info = IWorkflowInfo(self.context) try: wf_info.fireTransition(transition_id) self.flash(_("Transition '%s' executed." % transition_id)) except InvalidTransitionError, error: self.flash(error, type="warning") self.redirect(self.url(self.context)) return