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

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

Add RESTDocument.

  • Property svn:keywords set to Id
File size: 11.3 KB
Line 
1## $Id: browser.py 12408 2015-01-06 09:15:21Z 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        self.context.addDocument(document)
138        doctype = getUtility(IDocumentsUtils).SELECTABLE_DOCTYPES_DICT[doctype]
139        self.flash(_('${a} added.', mapping = {'a': doctype}))
140        ob_class = self.__implemented__.__name__.replace('waeup.ikoba.','')
141        self.context.__parent__.logger.info(
142            '%s - added: %s %s' % (ob_class, doctype, document.document_id))
143        self.redirect(self.url(self.context, u'manage'))
144        return
145
146    @action(_('Cancel'), validator=NullValidator)
147    def cancel(self, **data):
148        self.redirect(self.url(self.context))
149
150
151class DocumentDisplayFormPage(IkobaDisplayFormPage):
152    """ Page to display document data
153    """
154    grok.context(IPublicDocument)
155    grok.name('index')
156    grok.require('waeup.viewDocuments')
157    grok.template('documentpage')
158    pnav = 2
159
160    @property
161    def form_fields(self):
162        return grok.AutoFields(self.context.form_fields_interface)
163
164    @property
165    def label(self):
166        return self.context.title
167
168
169class HTMLDocumentDisplayFormPage(DocumentDisplayFormPage):
170    """ Page to display html document data
171    """
172    grok.context(IHTMLDocument)
173    grok.template('htmldocumentpage')
174
175    @property
176    def form_fields(self):
177        return grok.AutoFields(self.context.form_fields_interface).omit(
178            'html_dict', 'html_multilingual')
179
180    @property
181    def html(self):
182        lang = self.request.cookies.get('ikoba.language')
183        html = self.context.html_dict.get(lang,'')
184        if html =='':
185            portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
186            html = self.context.html_dict.get(portal_language,'')
187        return html
188
189
190class HTMLDocumentDisplayContentPage(IkobaPage):
191    """ Page to display the html content of document
192    """
193    grok.context(IHTMLDocument)
194    grok.name('display')
195    grok.template('htmldisplaypage')
196    grok.require('waeup.Public')
197
198    @property
199    def label(self):
200        return self.context.title
201
202    def update(self):
203        if self.context.state != PUBLISHED:
204            self.flash(_('The document requested has not yet been published.'),
205                type="warning")
206            self.redirect(self.application_url())
207        super(HTMLDocumentDisplayContentPage, self).update()
208        return
209
210    @property
211    def content(self):
212        lang = self.request.cookies.get('ikoba.language')
213        html = self.context.html_dict.get(lang,'')
214        if html =='':
215            portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
216            html = self.context.html_dict.get(portal_language,'')
217        return html
218
219
220class RESTDocumentDisplayFormPage(HTMLDocumentDisplayFormPage):
221    """ Page to display html document data
222    """
223    grok.context(IRESTDocument)
224
225    @property
226    def form_fields(self):
227        return grok.AutoFields(self.context.form_fields_interface).omit(
228            'html_dict', 'rest_multilingual')
229
230
231class RESTDocumentDisplayContentPage(HTMLDocumentDisplayContentPage):
232    """ Page to display the html content of document
233    """
234    grok.context(IRESTDocument)
235
236    label = None
237
238
239class DocumentManageFormPage(IkobaEditFormPage,
240                            LocalRoleAssignmentUtilityView):
241    """ View to manage document data
242    """
243    grok.context(IPublicDocument)
244    grok.name('manage')
245    grok.require('waeup.manageDocuments')
246    grok.template('documentmanagepage')
247    pnav = 2
248
249    taboneactions = [_('Save'),_('Cancel')]
250    tabthreeactions1 = [_('Remove selected local roles')]
251    tabthreeactions2 = [_('Add local role')]
252
253    deletion_warning = _('Are you sure?')
254
255    @property
256    def form_fields(self):
257        return grok.AutoFields(self.context.form_fields_interface)
258
259    def label(self):
260        return _('Manage document ') + self.context.document_id
261
262    @action(_('Save'), style='primary')
263    def save(self, **data):
264        return msave(self, **data)
265
266    @action(_('Cancel'), validator=NullValidator)
267    def cancel(self, **data):
268        self.redirect(self.url(self.context))
269        return
270
271    @action(_('Add local role'), validator=NullValidator)
272    def addLocalRole(self, **data):
273        return add_local_role(self,2,**data)
274
275    @action(_('Remove selected local roles'))
276    def delLocalRoles(self, **data):
277        return del_local_roles(self,2,**data)
278
279
280class HTMLDocumentManageFormPage(DocumentManageFormPage):
281    """ View to manage htmldocument data
282    """
283    grok.context(IHTMLDocument)
284    grok.template('htmldocumentmanagepage')
285
286    @action(_('Save'), style='primary')
287    def save(self, **data):
288        msave(self, **data)
289        html_multilingual = getattr(self.context, 'html_multilingual', None)
290        portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
291        self.context.html_dict = html2dict(html_multilingual, portal_language)
292        return
293
294
295class RESTDocumentManageFormPage(DocumentManageFormPage):
296    """ View to manage restdocument data
297    """
298    grok.context(IRESTDocument)
299    grok.template('htmldocumentmanagepage')
300
301    @action(_('Save'), style='primary')
302    def save(self, **data):
303        msave(self, **data)
304        html_multilingual = getattr(self.context, 'rest_multilingual', None)
305        portal_language = getUtility(IIkobaUtils).PORTAL_LANGUAGE
306        self.context.html_dict = rest2dict(html_multilingual, portal_language)
307        return
308
309
310class DocumentTriggerTransitionFormPage(IkobaEditFormPage):
311    """ View to trigger public document transitions
312    """
313    grok.context(IPublicDocument)
314    grok.name('trigtrans')
315    grok.require('waeup.triggerTransition')
316    grok.template('trigtrans')
317    label = _('Trigger document transition')
318    pnav = 2
319
320    def update(self):
321        return super(IkobaEditFormPage, self).update()
322
323    def getTransitions(self):
324        """Return a list of dicts of allowed transition ids and titles.
325
326        Each list entry provides keys ``name`` and ``title`` for
327        internal name and (human readable) title of a single
328        transition.
329        """
330        wf_info = IWorkflowInfo(self.context)
331        allowed_transitions = [t for t in wf_info.getManualTransitions()]
332        return [dict(name='', title=_('No transition'))] +[
333            dict(name=x, title=y) for x, y in allowed_transitions]
334
335    @action(_('Apply now'), style='primary')
336    def apply(self, **data):
337        form = self.request.form
338        if 'transition' in form and form['transition']:
339            transition_id = form['transition']
340            wf_info = IWorkflowInfo(self.context)
341            try:
342                wf_info.fireTransition(transition_id)
343                self.flash(_("Transition '%s' executed." % transition_id))
344            except InvalidTransitionError, error:
345                self.flash(error, type="warning")
346            self.redirect(self.url(self.context))
347        return
Note: See TracBrowser for help on using the repository browser.