source: main/waeup.ikoba/trunk/src/waeup/ikoba/documents/browser.py @ 12434

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

Modify redirect after adding documents.

Ensure that keys don't exist when adding documents.

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