Projet

Général

Profil

« Précédent | Suivant » 

Révision bfcb1e46

Ajouté par Frédéric Péters il y a plus de 4 ans

remove support for strongbox (#37967)

Voir les différences:

auquotidien/auquotidien.py
8 8
from modules import backoffice
9 9
from modules import categories_admin
10 10
from modules import payments_ui
11
from modules import strongbox_ui
12 11
from modules import formpage
13 12
from modules import template
14 13
from modules import root
......
28 27
rdb.register_directory('payments', payments_ui.PaymentsDirectory())
29 28
rdb.register_menu_item('payments/', _('Payments'))
30 29

  
31
rdb.register_directory('strongbox', strongbox_ui.StrongboxDirectory())
32
rdb.register_menu_item('strongbox/', _('Strongbox'))
33

  
34 30
rdb.register_directory('settings', admin.SettingsDirectory())
35 31

  
36 32
import wcs.admin.forms
auquotidien/modules/admin.py
22 22

  
23 23

  
24 24
class PanelDirectory(Directory):
25
    _q_exports = ['', 'update', 'permissions',
26
            'strongbox', 'domino']
25
    _q_exports = ['', 'update', 'permissions', 'domino']
27 26
    label = N_('Control Panel')
28 27

  
29 28
    domino = AbeliumDominoDirectory()
......
47 46
            form.add(SingleSelectWidget, 'payments', title = _('Admin role for payments'),
48 47
                    value = permissions_cfg.get('payments', None),
49 48
                    options = [(None, _('Nobody'), None)] + get_user_roles())
50
        if get_publisher().has_site_option('auquotidien-strongbox'):
51
            form.add(SingleSelectWidget, 'strongbox', title = _('Admin role for strongbox'),
52
                    value = permissions_cfg.get('strongbox', None),
53
                    options = [(None, _('Nobody'), None)] + get_user_roles())
54 49
        form.add_submit('submit', _('Submit'))
55 50
        form.add_submit('cancel', _('Cancel'))
56 51

  
......
66 61
            return r.getvalue()
67 62
        else:
68 63
            from wcs.admin.settings import cfg_submit
69
            cfg_submit(form, 'aq-permissions',
70
                        ('forms', 'payments', 'strongbox'))
71
            return redirect('..')
72

  
73
    def strongbox(self):
74
        if not get_publisher().has_site_option('strongbox'):
75
            raise errors.TraversalError()
76
        misc_cfg = get_cfg('misc', {})
77
        form = Form(enctype='multipart/form-data')
78
        form.add(CheckboxWidget, 'aq-strongbox', title=_('Strongbox Support'),
79
                value=misc_cfg.get('aq-strongbox'), required=False)
80

  
81
        form.add_submit('submit', _('Submit'))
82
        form.add_submit('cancel', _('Cancel'))
83

  
84
        if form.get_widget('cancel').parse():
85
            return redirect('..')
86

  
87
        if not form.is_submitted() or form.has_errors():
88
            get_response().breadcrumb.append(('aq/strongbox', _('Strongbox Support')))
89
            html_top('settings', _('Strongbox Support'))
90
            r = TemplateIO(html=True)
91
            r += htmltext('<h2>%s</h2>') % _('Strongbox Support')
92
            r += form.render()
93
            return r.getvalue()
94
        else:
95
            from wcs.admin.settings import cfg_submit
96
            cfg_submit(form, 'misc', ('aq-strongbox',))
64
            cfg_submit(form, 'aq-permissions', ('forms', 'payments'))
97 65
            return redirect('..')
98 66

  
99 67

  
100 68
class SettingsDirectory(wcs.admin.settings.SettingsDirectory):
101 69
    def _q_index(self):
102
        if not (get_publisher().has_site_option('auquotidien-payments') or
103
                get_publisher().has_site_option('auquotidien-strongvox')):
70
        if not get_publisher().has_site_option('auquotidien-payments'):
104 71
            return super(SettingsDirectory, self)._q_index()
105 72
        r = TemplateIO(html=True)
106 73
        r += htmltext(super(SettingsDirectory, self)._q_index())
......
109 76
        r += htmltext('<h2>%s</h2>') % _('Extra Options')
110 77
        r += htmltext('<ul>')
111 78
        r += htmltext('<li><a href="aq/permissions">%s</a></li>') % _('Permissions')
112
        if get_publisher().has_site_option('strongbox'):
113
            r += htmltext('<li><a href="aq/strongbox">%s</a></li>') % _('Strongbox Support')
114 79
        if get_publisher().has_site_option('domino'):
115 80
            r += htmltext('<li><a href="aq/domino">%s</a></li>') % _('Abelium Domino Integration')
116 81
        r += htmltext('</ul>')
auquotidien/modules/backoffice.py
28 28
    target = target.strip('/')
29 29
    if target == 'management':
30 30
        target = 'forms'
31
    if target == 'strongbox':
32
        if not get_publisher().has_site_option(target):
33
            # strongbox disabled in site-options.cfg
34
            return False
35
        if not get_cfg('misc', {}).get('aq-strongbox'):
36
            # strongbox disabled in settings panel
37
            return False
38 31
    admin_role = get_cfg('aq-permissions', {}).get(target, None)
39 32
    if not admin_role:
40 33
        return False
auquotidien/modules/myspace.py
25 25
from wcs.formdef import FormDef
26 26
import wcs.myspace
27 27

  
28
from .strongbox import StrongboxItem, StrongboxType
29 28
from .payments import Invoice, Regie, is_payment_supported
30 29

  
31 30
class MyInvoicesDirectory(Directory):
......
108 107
        return r.getvalue()
109 108

  
110 109

  
111
class StrongboxDirectory(Directory):
112
    _q_exports = ['', 'add', 'download', 'remove', 'pick', 'validate']
113

  
114
    def _q_traverse(self, path):
115
        if not get_cfg('misc', {}).get('aq-strongbox'):
116
            raise errors.TraversalError()
117
        get_response().breadcrumb.append(('strongbox/', _('Strongbox')))
118
        return Directory._q_traverse(self, path)
119

  
120
    def get_form(self):
121
        types = [(x.id, x.label) for x in StrongboxType.select()]
122
        form = Form(action='add', enctype='multipart/form-data')
123
        form.add(StringWidget, 'description', title=_('Description'), size=60)
124
        form.add(FileWidget, 'file', title=_('File'), required=True)
125
        form.add(SingleSelectWidget, 'type_id', title=_('Document Type'),
126
                 options = [(None, _('Not specified'))] + types)
127
        form.add(DateWidget, 'date_time', title = _('Document Date'))
128
        form.add_submit('submit', _('Upload'))
129
        return form
130

  
131
    def _q_index(self):
132
        template.html_top(_('Strongbox'))
133
        r = TemplateIO(html=True)
134

  
135
        # TODO: a paragraph of explanations here could be useful
136

  
137
        sffiles = list(StrongboxItem.get_with_indexed_value(
138
                        str('user_id'), str(get_request().user.id)))
139
        if sffiles:
140
            r += htmltext('<table id="strongbox-items">')
141
            r += htmltext('<tr><th></th><th>%s</th><th>%s</th><th></th></tr>') % (
142
                _('Type'), _('Expiration'))
143
        else:
144
            r += htmltext('<p>')
145
            r += _('There is currently nothing in your strongbox.')
146
            r += htmltext('</p>')
147
        has_items_to_validate = False
148
        for i, sffile in enumerate(sffiles):
149
            expired = False
150
            if not sffile.validated_time:
151
                has_items_to_validate = True
152
                continue
153
            if sffile.expiration_time and sffile.expiration_time < time.localtime():
154
                expired = True
155
            if i%2:
156
                classnames = ['odd']
157
            else:
158
                classnames = ['even']
159
            if expired:
160
                classnames.append('expired')
161
            r += htmltext('<tr class="%s">') % ' '.join(classnames)
162
            r += htmltext('<td class="label">')
163
            r += sffile.get_display_name()
164
            r += htmltext('</td>')
165
            if sffile.type_id:
166
                r += htmltext('<td class="type">%s</td>') % StrongboxType.get(sffile.type_id).label
167
            else:
168
                r += htmltext('<td class="type">-</td>')
169
            if sffile.expiration_time:
170
                r += htmltext('<td class="expiration">%s') % strftime(misc.date_format(), sffile.expiration_time)
171
                if expired:
172
                    r += ' (%s)' % _('expired')
173
                r += htmltext('</td>')
174
            else:
175
                r += htmltext('<td class="expiration">-</td>')
176
            r += htmltext('<td class="actions">')
177
            r += htmltext(' [<a href="download?id=%s">%s</a>] ') % (sffile.id, _('download'))
178
            r += htmltext('[<a rel="popup" href="remove?id=%s">%s</a>] ') % (sffile.id, _('remove'))
179
            r += htmltext('</td>')
180
            r += htmltext('</tr>')
181

  
182
        if has_items_to_validate:
183
            r += htmltext('<tr><td colspan="4"><h3>%s</h3></td></tr>') % _('Proposed Items')
184
            for sffile in sffiles:
185
                if sffile.validated_time:
186
                    continue
187
                if sffile.expiration_time and sffile.expiration_time < time.localtime():
188
                    expired = True
189
                if i%2:
190
                    classnames = ['odd']
191
                else:
192
                    classnames = ['even']
193
                if expired:
194
                    classnames.append('expired')
195
                r += htmltext('<tr class="%s">') % ' '.join(classnames)
196

  
197
                r += htmltext('<td class="label">')
198
                r += sffile.get_display_name()
199
                r += htmltext('</td>')
200
                if sffile.type_id:
201
                    r += htmltext('<td class="type">%s</td>') % StrongboxType.get(sffile.type_id).label
202
                else:
203
                    r += htmltext('<td class="type">-</td>')
204

  
205
                if sffile.expiration_time:
206
                    r += htmltext('<td class="expiration">%s') % strftime(misc.date_format(), sffile.expiration_time)
207
                    if expired:
208
                        r += ' (%s)' % _('expired')
209
                    r += htmltext('</td>')
210
                else:
211
                    r += htmltext('<td class="expiration">-</td>')
212
                r += htmltext('<td class="actions">')
213
                r += htmltext(' [<a href="download?id=%s">%s</a>] ') % (sffile.id, _('download'))
214
                r += htmltext(' [<a href="validate?id=%s">%s</a>] ') % (sffile.id, _('validate'))
215
                r += htmltext(' [<a href="remove?id=%s">%s</a>] ') % (sffile.id, _('reject'))
216
                r += htmltext('</td>')
217
                r += htmltext('</tr>')
218
        if sffiles:
219
            r += htmltext('</table>')
220

  
221
        r += htmltext('<h3>%s</h3>') % _('Add a file to the strongbox')
222
        form = self.get_form()
223
        r += form.render()
224
        return r.getvalue()
225

  
226
    def add(self):
227
        form = self.get_form()
228
        if not form.is_submitted():
229
            if get_request().form.get('mode') == 'pick':
230
                return redirect('pick')
231
            else:
232
                return redirect('.')
233

  
234
        sffile = StrongboxItem()
235
        sffile.user_id = get_request().user.id
236
        sffile.description = form.get_widget('description').parse()
237
        sffile.validated_time = time.localtime()
238
        sffile.type_id = form.get_widget('type_id').parse()
239
        v = form.get_widget('date_time').parse()
240
        sffile.set_expiration_time_from_date(v)
241
        sffile.store()
242
        sffile.set_file(form.get_widget('file').parse())
243
        sffile.store()
244
        if get_request().form.get('mode') == 'pick':
245
            return redirect('pick')
246
        else:
247
            return redirect('.')
248

  
249
    def download(self):
250
        id = get_request().form.get('id')
251
        if not id:
252
            raise errors.TraversalError()
253
        try:
254
            sffile = StrongboxItem.get(id)
255
        except KeyError:
256
            raise errors.TraversalError()
257
        if str(sffile.user_id) != str(get_request().user.id):
258
            raise errors.TraversalError()
259

  
260
        filename = sffile.file.filename
261
        fd = file(filename)
262
        size = os.path.getsize(filename)
263
        response = get_response()
264
        response.set_content_type('application/octet-stream')
265
        response.set_header('content-disposition', 'attachment; filename="%s"' % sffile.file.base_filename)
266
        return FileStream(fd, size)
267

  
268
    def validate(self):
269
        id = get_request().form.get('id')
270
        if not id:
271
            raise errors.TraversalError()
272
        try:
273
            sffile = StrongboxItem.get(id)
274
        except KeyError:
275
            raise errors.TraversalError()
276
        if str(sffile.user_id) != str(get_request().user.id):
277
            raise errors.TraversalError()
278
        sffile.validated_time = time.time()
279
        sffile.store()
280
        return redirect('.')
281

  
282
    def remove(self):
283
        id = get_request().form.get('id')
284
        if not id:
285
            raise errors.TraversalError()
286
        try:
287
            sffile = StrongboxItem.get(id)
288
        except KeyError:
289
            raise errors.TraversalError()
290
        if str(sffile.user_id) != str(get_request().user.id):
291
            raise errors.TraversalError()
292

  
293
        r = TemplateIO(html=True)
294
        form = Form(enctype='multipart/form-data')
295
        form.add_hidden('id', get_request().form.get('id'))
296
        form.widgets.append(HtmlWidget('<p>%s</p>' % _(
297
                        'You are about to irrevocably delete this item from your strongbox.')))
298
        form.add_submit('submit', _('Submit'))
299
        form.add_submit('cancel', _('Cancel'))
300
        if form.get_submit() == 'cancel':
301
            return redirect('.')
302
        if not form.is_submitted() or form.has_errors():
303
            if sffile.type_id:
304
                r += htmltext('<h2>%s</h2>') % _('Deleting %(filetype)s: %(filename)s') % {
305
                        'filetype': StrongboxType.get(sffile.type_id).label,
306
                        'filename': sffile.get_display_name()
307
                    }
308
            else:
309
                r += htmltext('<h2>%s</h2>') % _('Deleting %(filename)s') % {'filename': sffile.get_display_name()}
310
            r += form.render()
311
            return r.getvalue()
312
        else:
313
            sffile.remove_self()
314
            sffile.remove_file()
315
            return redirect('.')
316

  
317
    def picked_file(self):
318
        get_response().set_content_type('application/json')
319
        sffile = StrongboxItem.get(get_request().form.get('val'))
320
        sffile.file.fp = file(sffile.file.filename)
321
        if sffile.user_id != get_request().user.id:
322
            raise errors.TraversalError()
323
        # XXX: this will copy the file, it would be quite nice if it was
324
        # possible to just make it a symlink to the sffile
325
        token = get_session().add_tempfile(sffile.file)
326
        return json.dumps({'token': token, 'filename': sffile.file.base_filename})
327

  
328
    def pick(self):
329
        if get_request().form.get('select') == 'true':
330
            return self.picked_file()
331
        r = TemplateIO(html=True)
332
        root_url = get_publisher().get_root_url()
333
        sffiles = list(StrongboxItem.get_with_indexed_value(
334
                        str('user_id'), str(get_request().user.id)))
335
        r += htmltext('<h2>%s</h2>') % _('Pick a file')
336

  
337
        if not sffiles:
338
            r += htmltext('<p>')
339
            r += _('You do not have any file in your strongbox at the moment.')
340
            r += htmltext('</p>')
341
            r += htmltext('<div class="buttons">')
342
            r += htmltext('<a href="%smyspace/strongbox/" target="_blank">%s</a>') % (root_url,
343
                _('Open Strongbox Management'))
344
            r += htmltext('</div>')
345
        else:
346
            r += htmltext('<form id="strongbox-pick">')
347
            r += htmltext('<ul>')
348
            for sffile in sffiles:
349
                r += htmltext('<li><label><input type="radio" name="file" value="%s"/>%s</label>') % (
350
                                sffile.id, sffile.get_display_name())
351
                r += htmltext(' [<a href="%smyspace/strongbox/download?id=%s">%s</a>] ') % (
352
                                root_url, sffile.id, _('view'))
353
                r += htmltext('</li>')
354
            r += htmltext('</ul>')
355

  
356
            r += htmltext('<div class="buttons">')
357
            r += htmltext('<input name="cancel" type="button" value="%s"/>') % _('Cancel')
358
            r += ' '
359
            r += htmltext('<input name="pick" type="button" value="%s"/>') % _('Pick')
360
            r += htmltext('</div>')
361
            r += htmltext('</form>')
362
        return r.getvalue()
363

  
364

  
365 110
class JsonDirectory(Directory):
366 111
    '''Export of several lists in json, related to the current user or the
367 112
       SAMLv2 NameID we'd get in the URL'''
......
410 155

  
411 156
class MyspaceDirectory(wcs.myspace.MyspaceDirectory):
412 157
    _q_exports = ['', 'profile', 'new', 'password', 'remove', 'drafts', 'forms',
413
            'strongbox', 'invoices', 'json']
158
            'invoices', 'json']
414 159

  
415
    strongbox = StrongboxDirectory()
416 160
    invoices = MyInvoicesDirectory()
417 161
    json = JsonDirectory()
418 162

  
......
457 201
                profile_links.append('<a href="#my-profile">%s</a>' % _('My Profile'))
458 202
        if user_forms:
459 203
            profile_links.append('<a href="#my-forms">%s</a>' % _('My Forms'))
460
        if get_cfg('misc', {}).get('aq-strongbox'):
461
            profile_links.append('<a href="strongbox/">%s</a>' % _('My Strongbox'))
462 204
        if is_payment_supported():
463 205
            profile_links.append('<a href="invoices/">%s</a>' % _('My Invoices'))
464 206

  
auquotidien/modules/strongbox.py
1
import os
2
import time
3

  
4
from quixote import get_publisher
5
from wcs.qommon.storage import StorableObject
6
from wcs.qommon import misc
7

  
8
class StrongboxType(StorableObject):
9
    _names = 'strongbox-types'
10

  
11
    id = None
12
    label = None
13
    validation_months = 0
14

  
15

  
16
class StrongboxFile():
17
    id = None
18
    orig_filename = None
19
    base_filename = None
20
    content_type = None
21
    charset = None
22

  
23
    def __init__(self, id, f):
24
        self.id = id
25
        self.orig_filename = f.orig_filename
26
        self.base_filename = f.base_filename
27
        self.content_type = f.content_type
28
        self.charset = f.charset
29
        self.fp = f.fp
30

  
31
    def __getstate__(self):
32
        odict = self.__dict__.copy()
33
        if not odict.has_key('fp'):
34
            return odict
35

  
36
        # XXX: add some locking
37
        del odict['fp']
38
        dirname = os.path.join(get_publisher().app_dir, 'strongbox-files')
39
        if not os.path.exists(dirname):
40
            os.mkdir(dirname)
41
        odict['filename'] = os.path.join(dirname, str(self.id))
42
        self.fp.seek(0)
43
        fd = file(odict['filename'], 'w')
44
        fd.write(self.fp.read())
45
        fd.close()
46
        return odict
47

  
48

  
49
class StrongboxItem(StorableObject):
50
    _names = 'strongbox-items'
51
    _hashed_indexes = ['user_id']
52

  
53
    user_id = None
54
    description = None
55
    file = None
56
    type_id = None
57
    expiration_time = None
58
    proposed_by = None
59
    proposed_time = None
60
    validated_time = None
61

  
62
    def get_display_name(self):
63
        if self.description:
64
            return self.description
65
        return self.file.base_filename
66

  
67
    def set_file(self, file):
68
        self.file = StrongboxFile(self.id, file)
69

  
70
    def remove_file(self):
71
        os.unlink(self.file.filename)
72

  
73
    def set_expiration_time_from_date(self, value):
74
        if not value:
75
            self.expiration_time = None
76
            return
77
        if not StrongboxType.has_key(self.type_id):
78
            return
79

  
80
        if not StrongboxType.get(self.type_id).validation_months:
81
            self.expiration_time = None
82
            return
83

  
84
        date = time.strptime(value, misc.date_format())
85
        year, month, day = date[:3]
86
        month += StrongboxType.get(self.type_id).validation_months
87
        while month > 12:
88
           year += 1
89
           month -= 12
90
        while True:
91
            try:
92
                self.expiration_time = time.strptime(
93
                       '%04d-%02d-%02d' % (year, month, day), '%Y-%m-%d')
94
            except ValueError:
95
                day -= 1
96
                continue
97
            break
98

  
auquotidien/modules/strongbox_ui.py
1
import time
2

  
3
from quixote import get_request, get_response, get_session, redirect
4
from quixote.directory import Directory, AccessControlled
5
from quixote.html import TemplateIO, htmltext
6

  
7
import wcs
8
import wcs.admin.root
9

  
10
from wcs.qommon import _
11
from wcs.qommon import errors, misc
12
from wcs.qommon.form import *
13
from wcs.qommon.backoffice.menu import html_top
14
from wcs.qommon import get_cfg
15

  
16
from .strongbox import StrongboxType, StrongboxItem
17

  
18

  
19

  
20
class StrongboxTypeDirectory(Directory):
21
    _q_exports = ['', 'edit', 'delete']
22

  
23
    def __init__(self, strongboxtype):
24
        self.strongboxtype = strongboxtype
25

  
26
    def _q_index(self):
27
        html_top('strongbox', title = _('Item Type: %s') % self.strongboxtype.label)
28
        r = TemplateIO(html=True)
29
        r += htmltext('<h2>%s</h2>') % _('Item Type: %s') % self.strongboxtype.label
30
        get_response().filter['sidebar'] = self.get_sidebar()
31
        r += get_session().display_message()
32

  
33
        if self.strongboxtype.validation_months:
34
            r += htmltext('<div class="bo-block">')
35
            r += htmltext('<ul>')
36
            r += htmltext('<li>')
37
            r += _('Number of months of validity:')
38
            r += ' '
39
            r += self.strongboxtype.validation_months
40
            r += htmltext('</li>')
41
            r += htmltext('</ul>')
42
            r += htmltext('</div>')
43

  
44
        return r.getvalue()
45

  
46
    def get_sidebar(self):
47
        r = TemplateIO(html=True)
48
        r += htmltext('<ul>')
49
        r += htmltext('<li><a href="edit">%s</a></li>') % _('Edit')
50
        r += htmltext('<li><a href="delete">%s</a></li>') % _('Delete')
51
        r += htmltext('</ul>')
52
        return r.getvalue()
53

  
54
    def edit(self):
55
        form = self.form()
56
        if form.get_submit() == 'cancel':
57
            return redirect('.')
58

  
59
        if form.is_submitted() and not form.has_errors():
60
            self.submit(form)
61
            return redirect('..')
62

  
63
        html_top('strongbox', title = _('Edit Item Type: %s') % self.strongboxtype.label)
64
        r = TemplateIO(html=True)
65
        r += htmltext('<h2>%s</h2>') % _('Edit Item Type: %s') % self.strongboxtype.label
66
        r += form.render()
67
        return r.getvalue()
68

  
69
    def form(self):
70
        form = Form(enctype='multipart/form-data')
71
        form.add(StringWidget, 'label', title = _('Label'), required = True,
72
                value = self.strongboxtype.label)
73
        form.add(IntWidget, 'validation_months', title=_('Number of months of validity'),
74
                value=self.strongboxtype.validation_months,
75
                hint=_('Use 0 if there is no expiration'))
76
        form.add_submit('submit', _('Submit'))
77
        form.add_submit('cancel', _('Cancel'))
78
        return form
79

  
80
    def submit(self, form):
81
        for k in ('label', 'validation_months'):
82
            widget = form.get_widget(k)
83
            if widget:
84
                setattr(self.strongboxtype, k, widget.parse())
85
        self.strongboxtype.store()
86

  
87
    def delete(self):
88
        form = Form(enctype='multipart/form-data')
89
        form.widgets.append(HtmlWidget('<p>%s</p>' % _(
90
                        'You are about to irrevocably delete this item type.')))
91
        form.add_submit('submit', _('Submit'))
92
        form.add_submit('cancel', _('Cancel'))
93
        if form.get_submit() == 'cancel':
94
            return redirect('..')
95
        if not form.is_submitted() or form.has_errors():
96
            get_response().breadcrumb.append(('delete', _('Delete')))
97
            html_top('strongbox', title = _('Delete Item Type'))
98
            r = TemplateIO(html=True)
99
            r += htmltext('<h2>%s</h2>') % _('Deleting Item Type: %s') % self.strongboxtype.label
100
            r += form.render()
101
            return r.getvalue()
102
        else:
103
            self.strongboxtype.remove_self()
104
            return redirect('..')
105

  
106

  
107
class StrongboxTypesDirectory(Directory):
108
    _q_exports = ['', 'new']
109

  
110
    def _q_traverse(self, path):
111
        get_response().breadcrumb.append(('types/', _('Item Types')))
112
        return Directory._q_traverse(self, path)
113

  
114
    def _q_index(self):
115
        return redirect('..')
116

  
117
    def new(self):
118
        type_ui = StrongboxTypeDirectory(StrongboxType())
119

  
120
        form = type_ui.form()
121
        if form.get_submit() == 'cancel':
122
            return redirect('.')
123

  
124
        if form.is_submitted() and not form.has_errors():
125
            type_ui.submit(form)
126
            return redirect('%s/' % type_ui.strongboxtype.id)
127

  
128
        get_response().breadcrumb.append(('new', _('New Item Type')))
129
        html_top('strongbox', title = _('New Item Type'))
130
        r = TemplateIO(html=True)
131
        r += htmltext('<h2>%s</h2>') % _('New Item Type')
132
        r += form.render()
133
        return r.getvalue()
134

  
135
    def _q_lookup(self, component):
136
        try:
137
            strongboxtype = StrongboxType.get(component)
138
        except KeyError:
139
            raise errors.TraversalError()
140
        get_response().breadcrumb.append((str(strongboxtype.id), strongboxtype.label))
141
        return StrongboxTypeDirectory(strongboxtype)
142

  
143

  
144
class StrongboxDirectory(AccessControlled, Directory):
145
    _q_exports = ['', 'types', 'add', 'add_to']
146
    label = N_('Strongbox')
147

  
148
    types = StrongboxTypesDirectory()
149

  
150
    def is_accessible(self, user):
151
        from .backoffice import check_visibility
152
        return check_visibility('strongbox', user)
153

  
154
    def _q_access(self):
155
        user = get_request().user
156
        if not user:
157
            raise errors.AccessUnauthorizedError()
158

  
159
        if not self.is_accessible(user):
160
            raise errors.AccessForbiddenError(
161
                    public_msg = _('You are not allowed to access Strongbox Management'),
162
                    location_hint = 'backoffice')
163

  
164
        get_response().breadcrumb.append(('strongbox/', _('Strongbox')))
165

  
166

  
167
    def _q_index(self):
168
        html_top('strongbox', _('Strongbox'))
169
        r = TemplateIO(html=True)
170
        get_response().filter['sidebar'] = self.get_sidebar()
171

  
172
        r += get_session().display_message()
173

  
174
        r += htmltext('<div class="splitcontent-left">')
175
        r += htmltext('<div class="bo-block">')
176
        r += htmltext('<h2>%s</h2>') % _('Propose a file to a user')
177
        form = Form(enctype='multipart/form-data')
178
        form.add(StringWidget, 'q', title = _('User'), required=True)
179
        form.add_submit('search', _('Search'))
180
        r += form.render()
181
        if form.is_submitted() and not form.has_errors():
182
            q = form.get_widget('q').parse()
183
            users = self.search_for_users(q)
184
            if users:
185
                if len(users) == 1:
186
                    return redirect('add_to?user_id=%s' % users[0].id)
187
                if len(users) < 50:
188
                    r += _('(first 50 users only)')
189
                r += htmltext('<ul>')
190
                for u in users:
191
                    r += htmltext('<li><a href="add_to?user_id=%s">%s</a></li>') % (u.id, u.display_name)
192
                r += htmltext('</ul>')
193
            else:
194
                r += _('No user found.')
195
        r += htmltext('</div>')
196
        r += htmltext('</div>')
197

  
198
        r += htmltext('<div class="splitcontent-right">')
199
        r += htmltext('<div class="bo-block">')
200
        types = StrongboxType.select()
201
        r += htmltext('<h2>%s</h2>') % _('Item Types')
202
        if not types:
203
            r += htmltext('<p>')
204
            r += _('There is no item types defined at the moment.')
205
            r += htmltext('</p>')
206

  
207
        r += htmltext('<ul class="biglist" id="strongbox-list">')
208
        for l in types:
209
            type_id = l.id
210
            r += htmltext('<li class="biglistitem" id="itemId_%s">') % type_id
211
            r += htmltext('<strong class="label"><a href="types/%s/">%s</a></strong>') % (type_id, l.label)
212
            r += htmltext('</li>')
213
        r += htmltext('</ul>')
214
        r += htmltext('</div>')
215
        r += htmltext('</div>')
216
        return r.getvalue()
217

  
218
    def get_sidebar(self):
219
        r = TemplateIO(html=True)
220
        r += htmltext('<ul id="sidebar-actions">')
221
        r += htmltext('  <li><a class="new-item" href="types/new">%s</a></li>') % _('New Item Type')
222
        r += htmltext('</ul>')
223
        return r.getvalue()
224

  
225
    def search_for_users(self, q):
226
        if hasattr(get_publisher().user_class, 'search'):
227
            return get_publisher().user_class.search(q)
228
        if q:
229
            users = [x for x in get_publisher().user_class.select()
230
                     if q in (x.name or '') or q in (x.email or '')]
231
            return users
232
        else:
233
            return []
234

  
235
    def get_form(self):
236
        types = [(x.id, x.label) for x in StrongboxType.select()]
237
        form = Form(action='add', enctype='multipart/form-data')
238
        form.add(StringWidget, 'description', title=_('Description'), size=60)
239
        form.add(FileWidget, 'file', title=_('File'), required=True)
240
        form.add(SingleSelectWidget, 'type_id', title=_('Document Type'),
241
                 options = [(None, _('Not specified'))] + types)
242
        form.add(DateWidget, 'date_time', title = _('Document Date'))
243
        form.add_submit('submit', _('Upload'))
244
        return form
245

  
246
    def add(self):
247
        form = self.get_form()
248
        form.add(StringWidget, 'user_id', title=_('User'))
249
        if not form.is_submitted():
250
           return redirect('.')
251

  
252
        sffile = StrongboxItem()
253
        sffile.user_id = form.get_widget('user_id').parse()
254
        sffile.description = form.get_widget('description').parse()
255
        sffile.proposed_time = time.localtime()
256
        sffile.proposed_id = get_request().user.id
257
        sffile.type_id = form.get_widget('type_id').parse()
258
        v = form.get_widget('date_time').parse()
259
        sffile.set_expiration_time_from_date(v)
260
        sffile.store()
261
        sffile.set_file(form.get_widget('file').parse())
262
        sffile.store()
263
        return redirect('.')
264

  
265
    def add_to(self):
266
        form = Form(enctype='multipart/form-data', action='add_to')
267
        form.add(StringWidget, 'user_id', title = _('User'), required=True)
268
        try:
269
            user_id = form.get_widget('user_id').parse()
270
            user = get_publisher().user_class.get(user_id)
271
        except:
272
            return redirect('.')
273
        if not user:
274
            return redirect('.')
275
        get_request().form = {}
276
        get_request().environ['REQUEST_METHOD'] = 'GET'
277

  
278
        html_top('strongbox', _('Strongbox'))
279
        r = TemplateIO(html=True)
280
        r += htmltext('<h2>%s %s</h2>') % (_('Propose a file to:'), user.display_name)
281
        form = self.get_form()
282
        form.add(HiddenWidget, 'user_id', title=_('User'), value=user.id)
283
        r += form.render()
284
        return r.getvalue()

Formats disponibles : Unified diff