Projet

Général

Profil

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

root / auquotidien / modules / events_ui.py @ 8b02623d

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

    
18
from events import Event, RemoteCalendar, get_default_event_tags
19

    
20

    
21

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
140

    
141

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

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

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

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

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

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

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

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

    
178

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

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

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

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

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

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

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

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

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

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

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

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

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

    
299

    
300

    
301

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

    
306
    remote = RemoteCalendarsDirectory()
307

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

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

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

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

    
324

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

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

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

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

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

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

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

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

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

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

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

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

    
417
    def listing(self):
418
        return redirect('.')
(16-16/27)