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

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

Add documents package.

File size: 11.5 KB
Line 
1## $Id: browser.py 12413 2015-01-07 09:20:45Z 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, IObjectHistory, IKofaObject, IKofaUtils)
39from waeup.kofa.browser.layout import (
40    KofaPage, KofaEditFormPage, KofaAddFormPage, KofaDisplayFormPage,
41    KofaForm, 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
85
86class DocumentsContainerManageFormPage(KofaEditFormPage,
87                                      LocalRoleAssignmentUtilityView):
88    """The manage page for customer containers.
89    """
90    grok.context(IDocumentsContainer)
91    grok.name('manage')
92    grok.require('waeup.manageDocuments')
93    grok.template('containermanagepage')
94    pnav = 2
95    label = _('Manage document section')
96
97    @action(_('Add document'), validator=NullValidator, style='primary')
98    def addSubunit(self, **data):
99        self.redirect(self.url(self.context, 'adddoc'))
100        return
101
102    @jsaction(_('Remove selected documents'))
103    def delDocuments(self, **data):
104        delSubobjects(self, redirect='manage', tab='2')
105        return
106
107    @action(_('Cancel'), validator=NullValidator)
108    def cancel(self, **data):
109        self.redirect(self.url(self.context))
110        return
111
112
113class DocumentAddFormPage(KofaAddFormPage):
114    """Add-form to add a customer.
115    """
116    grok.context(IDocumentsContainer)
117    grok.require('waeup.manageDocuments')
118    grok.name('adddoc')
119    grok.template('documentaddform')
120    label = _('Add document')
121    pnav = 2
122
123    form_fields = grok.AutoFields(IPublicDocument)
124
125    @property
126    def selectable_doctypes(self):
127        doctypes = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT
128        return sorted(doctypes.items())
129
130    @action(_('Add document'), style='primary')
131    def createDocument(self, **data):
132        form = self.request.form
133        doctype = form.get('doctype', None)
134        # Here we can create various instances of PublicDocument derived
135        # classes depending on the doctype parameter given in form.
136        document = createObject('waeup.%s' % doctype)
137        self.applyData(document, **data)
138        try:
139            self.context.addDocument(document)
140        except KeyError:
141            self.flash(_('The id chosen already exists.'),
142                       type='danger')
143            return
144        doctype = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT[doctype]
145        self.flash(_('${a} added.', mapping = {'a': doctype}))
146        ob_class = self.__implemented__.__name__.replace('waeup.kofa.','')
147        self.context.__parent__.logger.info(
148            '%s - added: %s %s' % (ob_class, doctype, document.document_id))
149        self.redirect(self.url(self.context) +
150            '/%s/manage' % document.document_id)
151        return
152
153    @action(_('Cancel'), validator=NullValidator)
154    def cancel(self, **data):
155        self.redirect(self.url(self.context))
156
157
158class DocumentDisplayFormPage(KofaDisplayFormPage):
159    """ Page to display document data
160    """
161    grok.context(IPublicDocument)
162    grok.name('index')
163    grok.require('waeup.viewDocuments')
164    grok.template('documentpage')
165    pnav = 2
166
167    @property
168    def form_fields(self):
169        return grok.AutoFields(self.context.form_fields_interface)
170
171    @property
172    def label(self):
173        return self.context.title
174
175
176class HTMLDocumentDisplayFormPage(DocumentDisplayFormPage):
177    """ Page to display html document data
178    """
179    grok.context(IHTMLDocument)
180    grok.template('htmldocumentpage')
181
182    @property
183    def form_fields(self):
184        return grok.AutoFields(self.context.form_fields_interface).omit(
185            'html_dict', 'html_multilingual')
186
187    @property
188    def html(self):
189        lang = self.request.cookies.get('kofa.language')
190        html = self.context.html_dict.get(lang,'')
191        if html =='':
192            portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
193            html = self.context.html_dict.get(portal_language,'')
194        return html
195
196
197class HTMLDocumentDisplayContentPage(KofaPage):
198    """ Page to display the html content of document
199    """
200    grok.context(IHTMLDocument)
201    grok.name('display')
202    grok.template('htmldisplaypage')
203    grok.require('waeup.Public')
204
205    @property
206    def label(self):
207        return self.context.title
208
209    def update(self):
210        if self.context.state != PUBLISHED:
211            self.flash(_('The document requested has not yet been published.'),
212                type="warning")
213            self.redirect(self.application_url())
214        super(HTMLDocumentDisplayContentPage, self).update()
215        return
216
217    @property
218    def content(self):
219        lang = self.request.cookies.get('kofa.language')
220        html = self.context.html_dict.get(lang,'')
221        if html =='':
222            portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
223            html = self.context.html_dict.get(portal_language,'')
224        return html
225
226
227class RESTDocumentDisplayFormPage(HTMLDocumentDisplayFormPage):
228    """ Page to display html document data
229    """
230    grok.context(IRESTDocument)
231
232    @property
233    def form_fields(self):
234        return grok.AutoFields(self.context.form_fields_interface).omit(
235            'html_dict', 'rest_multilingual')
236
237
238class RESTDocumentDisplayContentPage(HTMLDocumentDisplayContentPage):
239    """ Page to display the html content of document
240    """
241    grok.context(IRESTDocument)
242
243    label = None
244
245
246class DocumentManageFormPage(KofaEditFormPage,
247                            LocalRoleAssignmentUtilityView):
248    """ View to manage document data
249    """
250    grok.context(IPublicDocument)
251    grok.name('manage')
252    grok.require('waeup.manageDocuments')
253    grok.template('documentmanagepage')
254    pnav = 2
255
256    taboneactions = [_('Save'),_('Cancel')]
257    tabthreeactions1 = [_('Remove selected local roles')]
258    tabthreeactions2 = [_('Add local role')]
259
260    deletion_warning = _('Are you sure?')
261
262    @property
263    def form_fields(self):
264        return grok.AutoFields(self.context.form_fields_interface)
265
266    def label(self):
267        return _('Manage document ') + self.context.document_id
268
269    @action(_('Save'), style='primary')
270    def save(self, **data):
271        return msave(self, **data)
272
273    @action(_('Cancel'), validator=NullValidator)
274    def cancel(self, **data):
275        self.redirect(self.url(self.context))
276        return
277
278    @action(_('Add local role'), validator=NullValidator)
279    def addLocalRole(self, **data):
280        return add_local_role(self,2,**data)
281
282    @action(_('Remove selected local roles'))
283    def delLocalRoles(self, **data):
284        return del_local_roles(self,2,**data)
285
286
287class HTMLDocumentManageFormPage(DocumentManageFormPage):
288    """ View to manage htmldocument data
289    """
290    grok.context(IHTMLDocument)
291    grok.template('htmldocumentmanagepage')
292
293    @action(_('Save'), style='primary')
294    def save(self, **data):
295        msave(self, **data)
296        html_multilingual = getattr(self.context, 'html_multilingual', None)
297        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
298        self.context.html_dict = html2dict(html_multilingual, portal_language)
299        return
300
301
302class RESTDocumentManageFormPage(DocumentManageFormPage):
303    """ View to manage restdocument data
304    """
305    grok.context(IRESTDocument)
306    grok.template('htmldocumentmanagepage')
307
308    @action(_('Save'), style='primary')
309    def save(self, **data):
310        msave(self, **data)
311        html_multilingual = getattr(self.context, 'rest_multilingual', None)
312        portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
313        self.context.html_dict = rest2dict(html_multilingual, portal_language)
314        return
315
316
317class DocumentTriggerTransitionFormPage(KofaEditFormPage):
318    """ View to trigger public document transitions
319    """
320    grok.context(IPublicDocument)
321    grok.name('trigtrans')
322    grok.require('waeup.triggerTransition')
323    grok.template('trigtrans')
324    label = _('Trigger document transition')
325    pnav = 2
326
327    def update(self):
328        return super(KofaEditFormPage, self).update()
329
330    def getTransitions(self):
331        """Return a list of dicts of allowed transition ids and titles.
332
333        Each list entry provides keys ``name`` and ``title`` for
334        internal name and (human readable) title of a single
335        transition.
336        """
337        wf_info = IWorkflowInfo(self.context)
338        allowed_transitions = [t for t in wf_info.getManualTransitions()]
339        return [dict(name='', title=_('No transition'))] +[
340            dict(name=x, title=y) for x, y in allowed_transitions]
341
342    @action(_('Apply now'), style='primary')
343    def apply(self, **data):
344        form = self.request.form
345        if 'transition' in form and form['transition']:
346            transition_id = form['transition']
347            wf_info = IWorkflowInfo(self.context)
348            try:
349                wf_info.fireTransition(transition_id)
350                self.flash(_("Transition '%s' executed." % transition_id))
351            except InvalidTransitionError, error:
352                self.flash(error, type="warning")
353            self.redirect(self.url(self.context))
354        return
Note: See TracBrowser for help on using the repository browser.