source: main/waeup.kofa/trunk/src/waeup/kofa/documents/browser.py @ 13213

Last change on this file since 13213 was 13144, checked in by Henrik Bettermann, 10 years ago

More docs and adjustments in Python code.

  • Property svn:keywords set to Id
File size: 12.6 KB
Line 
1## $Id: browser.py 13144 2015-07-07 05:21:14Z henrik $
2##
3## Copyright (C) 2014 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""UI components for documents offered for download by the company.
19"""
20
21import sys
22import grok
23import pytz
24from urllib import urlencode
25from datetime import datetime
26from hurry.workflow.interfaces import (
27    IWorkflowInfo, IWorkflowState, InvalidTransitionError)
28from zope.event import notify
29from zope.i18n import translate
30from zope.catalog.interfaces import ICatalog
31from zope.component import queryUtility, getUtility, createObject
32from zope.schema.interfaces import ConstraintNotSatisfied, RequiredMissing
33from zope.formlib.textwidgets import BytesDisplayWidget
34from zope.security import checkPermission
35from waeup.kofa.utils.helpers import html2dict, rest2dict
36from waeup.kofa.interfaces import MessageFactory as _
37from waeup.kofa.interfaces import (
38    IContactForm, IKofaObject, IKofaUtils, DOCLINK)
39from waeup.kofa.browser.layout import (
40    KofaPage, KofaEditFormPage, KofaAddFormPage, KofaDisplayFormPage,
41    NullValidator, jsaction, action, UtilityView)
42from waeup.kofa.widgets.datewidget import (
43    FriendlyDateWidget, FriendlyDateDisplayWidget,
44    FriendlyDatetimeDisplayWidget)
45from waeup.kofa.browser.breadcrumbs import Breadcrumb
46from waeup.kofa.browser.pages import (
47    delSubobjects, add_local_role, del_local_roles, msave,
48    LocalRoleAssignmentUtilityView)
49
50from waeup.kofa.documents.interfaces import (
51    IDocumentsContainer, IPublicDocument,
52    IHTMLDocument, IRESTDocument, IDocumentsUtils)
53from waeup.kofa.documents.workflow import PUBLISHED
54
55grok.context(IKofaObject) # Make IKofaObject the default context
56grok.templatedir('browser_templates')
57
58
59class DocumentsBreadcrumb(Breadcrumb):
60    """A breadcrumb for the customers container.
61    """
62    grok.context(IDocumentsContainer)
63    title = _('Documents')
64
65
66class DocumentBreadcrumb(Breadcrumb):
67    """A breadcrumb for the customer container.
68    """
69    grok.context(IPublicDocument)
70
71    def title(self):
72        return self.context.title
73
74
75class DocumentsContainerPage(KofaDisplayFormPage):
76    """The standard view for document containers.
77    """
78    grok.context(IDocumentsContainer)
79    grok.name('index')
80    grok.require('waeup.viewDocuments')
81    grok.template('containerpage')
82    pnav = 2
83    label = _('Documents')
84    doclink = DOCLINK + '/documents.html'
85
86
87class DocumentsContainerManageFormPage(KofaEditFormPage,
88                                      LocalRoleAssignmentUtilityView):
89    """The manage page for customer containers.
90    """
91    grok.context(IDocumentsContainer)
92    grok.name('manage')
93    grok.require('waeup.manageDocuments')
94    grok.template('containermanagepage')
95    pnav = 2
96    label = _('Manage document section')
97
98    @action(_('Add document'), validator=NullValidator, style='primary')
99    def addSubunit(self, **data):
100        self.redirect(self.url(self.context, 'adddoc'))
101        return
102
103    @jsaction(_('Remove selected documents'))
104    def delDocuments(self, **data):
105        delSubobjects(self, redirect='manage', tab='2')
106        return
107
108    @action(_('Cancel'), validator=NullValidator)
109    def cancel(self, **data):
110        self.redirect(self.url(self.context))
111        return
112
113
114class DocumentAddFormPage(KofaAddFormPage):
115    """Add-form to add a customer.
116    """
117    grok.context(IDocumentsContainer)
118    grok.require('waeup.manageDocuments')
119    grok.name('adddoc')
120    grok.template('documentaddform')
121    label = _('Add document')
122    pnav = 2
123
124    form_fields = grok.AutoFields(IPublicDocument)
125
126    @property
127    def selectable_doctypes(self):
128        doctypes = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT
129        return sorted(doctypes.items())
130
131    @action(_('Add document'), style='primary')
132    def createDocument(self, **data):
133        form = self.request.form
134        doctype = form.get('doctype', None)
135        # Here we can create various instances of PublicDocument derived
136        # classes depending on the doctype parameter given in form.
137        document = createObject('waeup.%s' % doctype)
138        self.applyData(document, **data)
139        try:
140            self.context.addDocument(document)
141        except KeyError:
142            self.flash(_('The id chosen already exists.'),
143                       type='danger')
144            return
145        doctype = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT[doctype]
146        self.flash(_('${a} added.', mapping = {'a': doctype}))
147        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
148        self.context.__parent__.logger.info(
149            '%s - added: %s %s' % (ob_class, doctype, document.document_id))
150        self.redirect(self.url(self.context) +
151            '/%s/manage' % document.document_id)
152        return
153
154    @action(_('Cancel'), validator=NullValidator)
155    def cancel(self, **data):
156        self.redirect(self.url(self.context))
157
158
159class DocumentDisplayFormPage(KofaDisplayFormPage):
160    """ Page to display document data
161    """
162    grok.context(IPublicDocument)
163    grok.name('index')
164    grok.require('waeup.viewDocuments')
165    grok.template('documentpage')
166    pnav = 2
167    doclink = DOCLINK + '/documents.html'
168
169    @property
170    def form_fields(self):
171        return grok.AutoFields(self.context.form_fields_interface)
172
173    @property
174    def label(self):
175        return self.context.title
176
177
178class HTMLDocumentDisplayFormPage(DocumentDisplayFormPage):
179    """ Page to display html document data
180    """
181    grok.context(IHTMLDocument)
182    grok.template('htmldocumentpage')
183
184    @property
185    def form_fields(self):
186        return grok.AutoFields(self.context.form_fields_interface).omit(
187            'html_dict', 'html_multilingual')
188
189    @property
190    def html(self):
191        lang = self.request.cookies.get('kofa.language')
192        html = self.context.html_dict.get(lang,'')
193        if html =='':
194            portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
195            html = self.context.html_dict.get(portal_language,'')
196        return html
197
198
199class HTMLDocumentDisplayContentPage(KofaPage):
200    """ Page to display the html content of document
201    """
202    grok.context(IHTMLDocument)
203    grok.name('display')
204    grok.template('htmldisplaypage')
205    grok.require('waeup.Public')
206
207    @property
208    def label(self):
209        return self.context.title
210
211    def update(self):
212        if self.context.state != PUBLISHED:
213            self.flash(_('The document requested has not yet been published.'),
214                type="warning")
215            self.redirect(self.application_url())
216        super(HTMLDocumentDisplayContentPage, self).update()
217        return
218
219    @property
220    def content(self):
221        lang = self.request.cookies.get('kofa.language')
222        html = self.context.html_dict.get(lang,'')
223        if html =='':
224            portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
225            html = self.context.html_dict.get(portal_language,'')
226        return html
227
228
229class RESTDocumentDisplayFormPage(HTMLDocumentDisplayFormPage):
230    """ Page to display html document data
231    """
232    grok.context(IRESTDocument)
233
234    @property
235    def form_fields(self):
236        return grok.AutoFields(self.context.form_fields_interface).omit(
237            'html_dict', 'rest_multilingual')
238
239
240class RESTDocumentDisplayContentPage(HTMLDocumentDisplayContentPage):
241    """ Page to display the html content of document
242    """
243    grok.context(IRESTDocument)
244
245    label = None
246
247
248class DocumentManageFormPage(KofaEditFormPage,
249                            LocalRoleAssignmentUtilityView):
250    """ View to manage document data
251    """
252    grok.context(IPublicDocument)
253    grok.name('manage')
254    grok.require('waeup.manageDocuments')
255    grok.template('documentmanagepage')
256    pnav = 2
257
258    taboneactions = [_('Save'),_('Cancel')]
259    tabthreeactions1 = [_('Remove selected local roles')]
260    tabthreeactions2 = [_('Add local role')]
261
262    deletion_warning = _('Are you sure?')
263
264    @property
265    def form_fields(self):
266        return grok.AutoFields(
267            self.context.form_fields_interface).omit('document_id')
268
269    def label(self):
270        return _('Manage document ') + self.context.document_id
271
272    @action(_('Save'), style='primary')
273    def save(self, **data):
274        return msave(self, **data)
275
276    @action(_('Cancel'), validator=NullValidator)
277    def cancel(self, **data):
278        self.redirect(self.url(self.context))
279        return
280
281    @action(_('Add local role'), validator=NullValidator)
282    def addLocalRole(self, **data):
283        return add_local_role(self,3,**data)
284
285    @action(_('Remove selected local roles'))
286    def delLocalRoles(self, **data):
287        return del_local_roles(self,3,**data)
288
289
290class HTMLDocumentManageFormPage(DocumentManageFormPage):
291    """ View to manage htmldocument data
292    """
293    grok.context(IHTMLDocument)
294    grok.template('htmldocumentmanagepage')
295
296    @action(_('Save'), style='primary')
297    def save(self, **data):
298        msave(self, **data)
299        html_multilingual = getattr(self.context, 'html_multilingual', None)
300        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
301        self.context.html_dict = html2dict(html_multilingual, portal_language)
302        return
303
304    # Actions must be repeated. They are not inherited from the parent class.
305
306    @action(_('Cancel'), validator=NullValidator)
307    def cancel(self, **data):
308        self.redirect(self.url(self.context))
309        return
310
311    @action(_('Add local role'), validator=NullValidator)
312    def addLocalRole(self, **data):
313        return add_local_role(self,3,**data)
314
315    @action(_('Remove selected local roles'))
316    def delLocalRoles(self, **data):
317        return del_local_roles(self,3,**data)
318
319class RESTDocumentManageFormPage(DocumentManageFormPage):
320    """ View to manage restdocument data
321    """
322    grok.context(IRESTDocument)
323    grok.template('htmldocumentmanagepage')
324
325    @action(_('Save'), style='primary')
326    def save(self, **data):
327        msave(self, **data)
328        html_multilingual = getattr(self.context, 'rest_multilingual', None)
329        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
330        self.context.html_dict = rest2dict(html_multilingual, portal_language)
331        return
332
333    # Actions must be repeated. They are not inherited from the parent class.
334
335    @action(_('Cancel'), validator=NullValidator)
336    def cancel(self, **data):
337        self.redirect(self.url(self.context))
338        return
339
340    @action(_('Add local role'), validator=NullValidator)
341    def addLocalRole(self, **data):
342        return add_local_role(self,3,**data)
343
344    @action(_('Remove selected local roles'))
345    def delLocalRoles(self, **data):
346        return del_local_roles(self,3,**data)
347
348class DocumentTriggerTransitionFormPage(KofaEditFormPage):
349    """ View to trigger public document transitions
350    """
351    grok.context(IPublicDocument)
352    grok.name('trigtrans')
353    grok.require('waeup.triggerTransition')
354    grok.template('trigtrans')
355    label = _('Trigger document transition')
356    pnav = 2
357
358    def update(self):
359        return super(KofaEditFormPage, self).update()
360
361    def getTransitions(self):
362        """Return a list of dicts of allowed transition ids and titles.
363
364        Each list entry provides keys ``name`` and ``title`` for
365        internal name and (human readable) title of a single
366        transition.
367        """
368        wf_info = IWorkflowInfo(self.context)
369        allowed_transitions = [t for t in wf_info.getManualTransitions()]
370        return [dict(name='', title=_('No transition'))] +[
371            dict(name=x, title=y) for x, y in allowed_transitions]
372
373    @action(_('Apply now'), style='primary')
374    def apply(self, **data):
375        form = self.request.form
376        if 'transition' in form and form['transition']:
377            transition_id = form['transition']
378            wf_info = IWorkflowInfo(self.context)
379            try:
380                wf_info.fireTransition(transition_id)
381                self.flash(_("Transition '%s' executed." % transition_id))
382            except InvalidTransitionError, error:
383                self.flash(error, type="warning")
384            self.redirect(self.url(self.context))
385        return
Note: See TracBrowser for help on using the repository browser.