Projet

Général

Profil

Télécharger (15,4 ko) Statistiques
| Branche: | Tag: | Révision:

root / extra / modules / events_ui.py @ c182b1ab

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 qommon.backoffice.menu import html_top
11
from qommon.admin.menu import command_icon
12
from qommon import get_cfg
13
from qommon import errors, misc
14
from qommon.form import *
15
from qommon.strftime import strftime
16

    
17
from events import Event, RemoteCalendar, get_default_event_tags
18

    
19

    
20

    
21
class RemoteCalendarDirectory(Directory):
22
    _q_exports = ['', 'edit', 'delete', 'update']
23

    
24
    def __init__(self, calendar):
25
        self.calendar = calendar
26

    
27
    def _q_index(self):
28
        form = Form(enctype='multipart/form-data')
29
        form.add_submit('edit', _('Edit'))
30
        form.add_submit('delete', _('Delete'))
31
        form.add_submit('update', _('Update'))
32
        form.add_submit('back', _('Back'))
33

    
34
        if form.get_submit() == 'edit':
35
            return redirect('edit')
36
        if form.get_submit() == 'update':
37
            return redirect('update')
38
        if form.get_submit() == 'delete':
39
            return redirect('delete')
40
        if form.get_submit() == 'back':
41
            return redirect('..')
42

    
43
        html_top('events', title = _('Remote Calendar: %s') % self.calendar.label)
44
        r = TemplateIO(html=True)
45
        r += htmltext('<h2>%s</h2>') % _('Remote Calendar: %s') % self.calendar.label
46

    
47
        r += get_session().display_message()
48

    
49
        r += htmltext('<p>')
50
        self.calendar.url
51
        if self.calendar.error:
52
            r += htmltext(' - <span class="error-message">%s</span>') % self.calendar.get_error_message()
53
        r += htmltext('</p>')
54

    
55
        if not self.calendar.content:
56
            r += htmltext('<p>')
57
            r += _('No content has been retrieved yet.')
58
            r += htmltext('</p>')
59
        else:
60
            r += htmltext('<ul>')
61
            for ev in sorted(self.calendar.events, lambda x,y: cmp(x.date_start, y.date_start)):
62
                r += htmltext('<li>')
63
                if ev.date_start:
64
                    r += strftime(misc.date_format(), ev.date_start)
65
                if ev.date_end and ev.date_start[:3] != ev.date_end[:3]:
66
                    r += ' - '
67
                    r += strftime(misc.date_format(), ev.date_start)
68

    
69
                r += ' : '
70
                if ev.url:
71
                    r += htmltext('<a href="%s">%s</a>') % (ev.url, ev.title)
72
                else:
73
                    r += ev.title
74
                r += htmltext('</li>')
75
            r += htmltext('</ul>')
76

    
77
        r += form.render()
78
        return r.getvalue()
79

    
80
    def edit(self):
81
        form = self.form()
82
        if form.get_submit() == 'cancel':
83
            return redirect('.')
84

    
85
        if form.is_submitted() and not form.has_errors():
86
            self.submit(form)
87
            return redirect('..')
88

    
89
        html_top('events', title = _('Edit Remote Calendar: %s') % self.calendar.label)
90
        r = TemplateIO(html=True)
91
        r += htmltext('<h2>%s</h2>') % _('Edit Remote Calendar: %s') % self.calendar.label
92
        r += form.render()
93
        return r.getvalue()
94

    
95
    def form(self):
96
        form = Form(enctype='multipart/form-data')
97
        form.add(StringWidget, 'label', title = _('Label'), required = True,
98
                value = self.calendar.label)
99
        form.add(StringWidget, 'url', title = _('URL'), required = True,
100
                value = self.calendar.url, size = 40)
101
        form.add_submit('submit', _('Submit'))
102
        form.add_submit('cancel', _('Cancel'))
103
        return form
104

    
105
    def submit(self, form):
106
        for k in ('label', 'url'):
107
            widget = form.get_widget(k)
108
            if widget:
109
                setattr(self.calendar, k, widget.parse())
110
        self.calendar.store()
111

    
112
    def delete(self):
113
        form = Form(enctype='multipart/form-data')
114
        form.widgets.append(HtmlWidget('<p>%s</p>' % _(
115
                        'You are about to irrevocably delete this remote calendar.')))
116
        form.add_submit('submit', _('Submit'))
117
        form.add_submit('cancel', _('Cancel'))
118
        if form.get_submit() == 'cancel':
119
            return redirect('..')
120
        if not form.is_submitted() or form.has_errors():
121
            get_response().breadcrumb.append(('delete', _('Delete')))
122
            html_top('events', title = _('Delete Remote Calendar'))
123
            r = TemplateIO(html=True)
124
            r += htmltext('<h2>%s</h2>') % _('Deleting Remote Calendar: %s') % self.calendar.label
125
            r += form.render()
126
            return r.getvalue()
127
        else:
128
            self.calendar.remove_self()
129
            return redirect('..')
130

    
131
    def update(self):
132
        get_session().message = ('info',
133
                _('Calendar update has been requested, reload in a few moments'))
134
        get_response().add_after_job('updating remote calendar',
135
                self.calendar.download_and_parse,
136
                fire_and_forget = True)
137
        return redirect('.')
138

    
139

    
140

    
141
class RemoteCalendarsDirectory(Directory):
142
    _q_exports = ['', 'new']
143

    
144
    def _q_traverse(self, path):
145
        get_response().breadcrumb.append(('remote/', _('Remote Calendars')))
146
        return Directory._q_traverse(self, path)
147

    
148
    def _q_index(self):
149
        return redirect('..')
150

    
151
    def new(self):
152
        calendar_ui = RemoteCalendarDirectory(RemoteCalendar())
153

    
154
        form = calendar_ui.form()
155
        if form.get_submit() == 'cancel':
156
            return redirect('.')
157

    
158
        if form.is_submitted() and not form.has_errors():
159
            calendar_ui.submit(form)
160
            return redirect('%s/' % calendar_ui.calendar.id)
161

    
162
        get_response().breadcrumb.append(('new', _('New Remote Calendar')))
163
        html_top('events', title = _('New Remote Calendar'))
164
        r = TemplateIO(html=True)
165
        r += htmltext('<h2>%s</h2>') % _('New Remote Calendar')
166
        r += form.render()
167
        return r.getvalue()
168

    
169
    def _q_lookup(self, component):
170
        try:
171
            event = RemoteCalendar.get(component)
172
        except KeyError:
173
            raise errors.TraversalError()
174
        get_response().breadcrumb.append((str(event.id), event.label))
175
        return RemoteCalendarDirectory(event)
176

    
177

    
178
class EventDirectory(Directory):
179
    _q_exports = ['', 'edit', 'delete']
180

    
181
    def __init__(self, event):
182
        self.event = event
183

    
184
    def _q_index(self):
185
        form = Form(enctype='multipart/form-data')
186
        form.add_submit('edit', _('Edit'))
187
        form.add_submit('delete', _('Delete'))
188
        form.add_submit('back', _('Back'))
189

    
190
        if form.get_submit() == 'edit':
191
            return redirect('edit')
192
        if form.get_submit() == 'delete':
193
            return redirect('delete')
194
        if form.get_submit() == 'back':
195
            return redirect('..')
196

    
197
        html_top('events', title = _('Event: %s') % self.event.title)
198
        r = TemplateIO(html=True)
199
        r += htmltext('<h2>%s</h2>') % _('Event: %s') % self.event.title
200
        r += htmltext('<p>')
201
        r += self.event.description
202
        r += htmltext('</p>')
203
        r += htmltext('<ul>')
204
        if self.event.location:
205
            r += htmltext('<li>%s: %s</li>') % (_('Location'), self.event.location)
206
        if self.event.organizer:
207
            r += htmltext('<li>%s: %s</li>') % (_('Organizer'), self.event.organizer)
208
        if self.event.url:
209
            r += htmltext('<li>%s: <a href="%s">%s</a></li>') % (_('URL'), self.event.url, self.event.url)
210
        r += htmltext('</ul>')
211

    
212
        if self.event.more_infos:
213
            r += htmltext('<p>')
214
            r += self.event.more_infos
215
            r += htmltext('</p>')
216

    
217
        r += form.render()
218
        return r.getvalue()
219

    
220
    def edit(self):
221
        form = self.form()
222
        if form.get_submit() == 'cancel':
223
            return redirect('.')
224

    
225
        if form.is_submitted() and not form.has_errors():
226
            self.submit(form)
227
            return redirect('..')
228

    
229
        html_top('events', title = _('Edit Event: %s') % self.event.title)
230
        r = TemplateIO(html=True)
231
        r += htmltext('<h2>%s</h2>') % _('Edit Event: %s') % self.event.title
232
        r += form.render()
233
        return r.getvalue()
234

    
235
    def form(self):
236
        form = Form(enctype='multipart/form-data')
237
        form.add(StringWidget, 'title', title = _('Title'), required = True,
238
                value = self.event.title)
239
        form.add(TextWidget, 'description', title = _('Description'),
240
                cols = 70, rows = 10,
241
                required = True, value = self.event.description)
242
        form.add(StringWidget, 'url', title = _('URL'), required = False,
243
                value = self.event.url, size = 40)
244
        form.add(DateWidget, 'date_start', title = _('Start Date'), required = True,
245
                value = strftime(misc.date_format(), self.event.date_start))
246
        form.add(DateWidget, 'date_end', title = _('End Date'), required = False,
247
                value = strftime(misc.date_format(), self.event.date_end))
248
        form.add(TextWidget, 'location', title = _('Location'),
249
                cols = 70, rows = 4,
250
                required = False, value = self.event.location)
251
        form.add(StringWidget, 'organizer', title = _('Organizer'), required = False,
252
                value = self.event.organizer, size = 40)
253
        form.add(TextWidget, 'more_infos', title = _('More informations'),
254
                cols = 70, rows = 10,
255
                required = False, value = self.event.more_infos)
256
        form.add(TagsWidget, 'keywords', title = _('Keywords'),
257
                value = self.event.keywords, size = 50,
258
                known_tags = get_cfg('misc', {}).get('event_tags', get_default_event_tags()))
259
        form.add_submit('submit', _('Submit'))
260
        form.add_submit('cancel', _('Cancel'))
261
        return form
262

    
263
    def submit(self, form):
264
        for k in ('title', 'description', 'url', 'date_start', 'date_end',
265
                    'organizer', 'location', 'more_infos', 'keywords'):
266
            widget = form.get_widget(k)
267
            if widget:
268
                if k in ('date_start', 'date_end'):
269
                    # convert dates to 9-item tuples
270
                    v = widget.parse()
271
                    if v:
272
                        setattr(self.event, k, time.strptime(v, misc.date_format()))
273
                    else:
274
                        setattr(self.event, k, None)
275
                else:
276
                    setattr(self.event, k, widget.parse())
277
        self.event.store()
278

    
279
    def delete(self):
280
        form = Form(enctype='multipart/form-data')
281
        form.widgets.append(HtmlWidget('<p>%s</p>' % _(
282
                        'You are about to irrevocably delete this event.')))
283
        form.add_submit('submit', _('Submit'))
284
        form.add_submit('cancel', _('Cancel'))
285
        if form.get_submit() == 'cancel':
286
            return redirect('..')
287
        if not form.is_submitted() or form.has_errors():
288
            get_response().breadcrumb.append(('delete', _('Delete')))
289
            html_top('events', title = _('Delete Event'))
290
            r = TemplateIO(html=True)
291
            r += htmltext('<h2>%s</h2>') % _('Deleting Event: %s') % self.event.title
292
            r += form.render()
293
            return r.getvalue()
294
        else:
295
            self.event.remove_self()
296
            return redirect('..')
297

    
298

    
299

    
300

    
301
class EventsDirectory(AccessControlled, Directory):
302
    _q_exports = ['', 'new', 'listing', 'remote']
303
    label = N_('Events')
304

    
305
    remote = RemoteCalendarsDirectory()
306

    
307
    def is_accessible(self, user):
308
        from .backoffice import check_visibility
309
        return check_visibility('events', user)
310

    
311
    def _q_access(self):
312
        user = get_request().user
313
        if not user:
314
            raise errors.AccessUnauthorizedError()
315

    
316
        if not self.is_accessible(user):
317
            raise errors.AccessForbiddenError(
318
                    public_msg = _('You are not allowed to access Events Management'),
319
                    location_hint = 'backoffice')
320

    
321
        get_response().breadcrumb.append(('events/', _('Events')))
322

    
323

    
324
    def _q_index(self):
325
        html_top('events', _('Events'))
326
        r = TemplateIO(html=True)
327

    
328
        get_response().filter['sidebar'] = self.get_sidebar()
329

    
330
        r += htmltext('<div class="splitcontent-left">')
331

    
332
        r += htmltext('<div class="bo-block">')
333
        events = Event.select()
334
        r += htmltext('<h2>%s</h2>') % _('Events')
335
        if not events:
336
            r += htmltext('<p>')
337
            r += _('There is no event defined at the moment.')
338
            r += htmltext('</p>')
339
        r += htmltext('<ul class="biglist" id="events-list">')
340
        for l in events:
341
            event_id = l.id
342
            r += htmltext('<li class="biglistitem" id="itemId_%s">') % event_id
343
            r += htmltext('<strong class="label"><a href="%s/">%s</a></strong>') % (event_id, l.title)
344
            r += ' - '
345
            r += l.format_date()
346
            r += htmltext('<p class="commands">')
347
            r += command_icon('%s/edit' % event_id, 'edit')
348
            r += command_icon('%s/delete' % event_id, 'remove')
349
            r += htmltext('</p></li>')
350
        r += htmltext('</ul>')
351
        r += htmltext('</div>')
352
        r += htmltext('</div>')
353

    
354
        r += htmltext('<div class="splitcontent-right">')
355
        r += htmltext('<div class="bo-block">')
356
        rcalendars = RemoteCalendar.select()
357
        r += htmltext('<h2>%s</h2>') % _('Remote Calendars')
358
        if not rcalendars:
359
            r += htmltext('<p>')
360
            r += _('There is no remote calendars defined at the moment.')
361
            r += htmltext('</p>')
362

    
363
        r += htmltext('<ul class="biglist" id="events-list">')
364
        for l in rcalendars:
365
            rcal_id = l.id
366
            r += htmltext('<li class="biglistitem" id="itemId_%s">') % rcal_id
367
            r += htmltext('<strong class="label"><a href="remote/%s/">%s</a></strong>') % (rcal_id, l.label)
368
            r += htmltext('<p class="details">')
369
            r += l.url
370
            if l.error:
371
                r += htmltext('<br /><span class="error-message">%s</span>') % l.get_error_message()
372
            r += htmltext('</p>')
373
            r += htmltext('<p class="commands">')
374
            r += command_icon('remote/%s/edit' % rcal_id, 'edit')
375
            r += command_icon('remote/%s/delete' % rcal_id, 'remove')
376
            r += htmltext('</p></li>')
377
        r += htmltext('</ul>')
378
        r += htmltext('</div>')
379
        r += htmltext('</div>')
380
        return r.getvalue()
381

    
382
    def get_sidebar(self):
383
        r = TemplateIO(html=True)
384
        r += htmltext('<ul id="sidebar-actions">')
385
        r += htmltext('  <li><a class="new-item" href="new">%s</a></li>') % _('New Event')
386
        r += htmltext('  <li><a class="new-item" href="remote/new">%s</a></li>') % _('New Remote Calendar')
387
        r += htmltext('</ul>')
388
        return r.getvalue()
389

    
390
    def new(self):
391
        event_ui = EventDirectory(Event())
392

    
393
        form = event_ui.form()
394
        if form.get_submit() == 'cancel':
395
            return redirect('.')
396

    
397
        if form.is_submitted() and not form.has_errors():
398
            event_ui.submit(form)
399
            return redirect('%s/' % event_ui.event.id)
400

    
401
        get_response().breadcrumb.append(('new', _('New Event')))
402
        html_top('events', title = _('New Event'))
403
        r = TemplateIO(html=True)
404
        r += htmltext('<h2>%s</h2>') % _('New Event')
405
        r += form.render()
406
        return r.getvalue()
407

    
408
    def _q_lookup(self, component):
409
        try:
410
            event = Event.get(component)
411
        except KeyError:
412
            raise errors.TraversalError()
413
        get_response().breadcrumb.append((str(event.id), event.title))
414
        return EventDirectory(event)
415

    
416
    def listing(self):
417
        return redirect('.')
(16-16/30)