import time import datetime from sets import Set from quixote.directory import Directory from quixote import get_publisher, get_request, redirect, get_session, get_response from quixote.html import htmltext, TemplateIO from wcs.qommon import _ from wcs.qommon import misc, template, errors, get_cfg from wcs.qommon.form import * from .events import Event, RemoteCalendar, get_default_event_tags class TagDirectory(Directory): def _q_lookup(self, component): events = Event.select() for remote_calendar in RemoteCalendar.select(): if remote_calendar.events: events.extend(remote_calendar.events) self.events = [x for x in events if component in (x.keywords or [])] self.events.sort(lambda x,y: cmp(x.date_start, y.date_start)) self.tag = component return self.display_events() def display_events(self): template.html_top(_('Agenda')) r = TemplateIO(html=True) if len(self.events) > 1: r += htmltext('

') r += _('%(nb)d events with %(keyword)s keyword') % { 'nb': len(self.events), 'keyword': self.tag } r += htmltext('

') if self.events: r += htmltext('
') for ev in self.events: r += htmltext(ev.as_html_dt_dd()) r += htmltext('
') else: r += htmltext('

') r += _('No event registered with the %s keyword.') % self.tag r += htmltext('

') return r.getvalue() class AgendaDirectory(Directory): _q_exports = ['', 'icalendar', 'tag', 'atom', 'filter'] year = None month = None tag = TagDirectory() def _q_traverse(self, path): get_response().breadcrumb.append(('agenda/', _('Agenda'))) self.year, self.month = time.localtime()[:2] if len(path) >= 1 and path[0].isdigit(): self.year, self.month = (None, None) self.year = int(path[0]) get_response().breadcrumb.append(('%s/' % self.year, self.year)) path = path[1:] if len(path) >= 1 and path[0] in [str(x) for x in range(1, 13)]: self.month = int(path[0]) get_response().breadcrumb.append(('%s/' % self.month, misc.get_month_name(self.month))) path = path[1:] if len(path) == 0: return redirect(get_request().get_path() + '/') return Directory._q_traverse(self, path) def _q_index(self): if self.month: r = TemplateIO(html=True) r += htmltext(self.display_month_links()) r += htmltext(self.display_month()) return r.getvalue() else: return redirect('..') def display_month(self): template.html_top(_('Agenda')) events = Event.select() remote_cal = get_request().form.get('cal') if remote_cal != 'local': if remote_cal: try: events = RemoteCalendar.get(remote_cal).events except KeyError: raise errors.TraversalError() if not events: events = [] else: for remote_calendar in RemoteCalendar.select(): if remote_calendar.events: events.extend(remote_calendar.events) events = [x for x in events if x.in_month(self.year, self.month)] events.sort(lambda x,y: cmp(x.date_start, y.date_start)) r = TemplateIO(html=True) if events: if len(events) > 1: r += htmltext('

') r += _('%(nb)d events for %(month_name)s %(year)s') % { 'nb': len(events), 'month_name': misc.get_month_name(self.month), 'year': self.year} r += htmltext('

') r += htmltext('
') for ev in events: r += htmltext(ev.as_html_dt_dd()) r += htmltext('
') else: r += htmltext('

') r += _('No event registered for the month of %s.') % '%s %s' % ( misc.get_month_name(self.month), self.year) r += htmltext('

') root_url = get_publisher().get_root_url() r += htmltext('
') r += htmltext('

') r += _('You can subscribe to this calendar:') r += htmltext('

') r += htmltext('') r += htmltext('
') return r.getvalue() def display_month_links(self): today = datetime.date(*(time.localtime()[:2] + (1,))) r = TemplateIO(html=True) r += htmltext('') return r.getvalue() def display_remote_calendars(self): r = TemplateIO(html=True) remote_calendars = [x for x in RemoteCalendar.select() if x.label] if not remote_calendars: return remote_calendars.sort(lambda x,y: cmp(x.label, y.label)) r += htmltext('

') remote_cal = get_request().form.get('cal') agenda_root_url = get_publisher().get_root_url() + 'agenda/' if remote_cal: r += htmltext('%s ') % (agenda_root_url, _('All')) else: r += htmltext('%s ') % (agenda_root_url, _('All')) if remote_cal != 'local': r += htmltext('%s ') % (agenda_root_url, _('Local')) else: r += htmltext('%s ') % (agenda_root_url, _('Local')) for cal in remote_calendars: if remote_cal == str(cal.id): r += htmltext('%s ') % ( agenda_root_url, cal.id, cal.label) else: r += htmltext('%s ') % (agenda_root_url, cal.id, cal.label) r += htmltext('

') return r.getvalue() def icalendar(self): if not Event.keys(): raise errors.TraversalError() response = get_response() response.set_content_type('text/calendar', 'utf-8') vcal = Event.as_vcalendar() if type(vcal) is unicode: return vcal.encode('utf-8') else: return vcal def atom(self): response = get_response() response.set_content_type('application/atom+xml') from pyatom import pyatom xmldoc = pyatom.XMLDoc() feed = pyatom.Feed() xmldoc.root_element = feed feed.title = get_cfg('misc', {}).get('sitename', 'Publik') + ' - ' + _('Agenda') feed.id = get_request().get_url() author_email = get_cfg('emails', {}).get('reply_to') if not author_email: author_email = get_cfg('emails', {}).get('from') if author_email: feed.authors.append(pyatom.Author(author_email)) feed.links.append(pyatom.Link(get_request().get_url(1) + '/')) year, month = time.localtime()[:2] nyear, nmonth = year, month+1 if nmonth > 12: nyear, nmonth = nyear+1, 1 events = [x for x in Event.select() if x.in_month(year, month) or x.in_month(nyear, nmonth)] events.sort(lambda x,y: cmp(x.date_start, y.date_start)) events.reverse() for item in events: entry = item.get_atom_entry() if entry is not None: feed.entries.append(entry) return str(feed) def filter(self, no_event=False): template.html_top(_('Agenda')) tags = get_cfg('misc', {}).get('event_tags') if not tags: tags = get_default_event_tags() remote_calendars = [x for x in RemoteCalendar.select() if x.label] form = Form(enctype='multipart/form-data') if tags and remote_calendars: form.widgets.append(HtmlWidget('
')) if tags: form.add(CheckboxesWidget, 'tags', title=_('Tags'), options=[(x,x) for x in tags], inline=False) if tags and remote_calendars: form.widgets.append(HtmlWidget('')) if remote_calendars: remote_calendars.sort(lambda x,y: cmp(x.label, y.label)) form.add(CheckboxesWidget, 'calendars', title=_('Calendars'), options=[('local', _('Local'))] + [(x.id, x.label) for x in remote_calendars], inline=False) if tags and remote_calendars: form.widgets.append(HtmlWidget('
')) form.add_submit('submit', _('Submit')) form.add_submit('cancel', _('Cancel')) if form.get_widget('cancel').parse(): return redirect('.') if no_event or not form.is_submitted(): r = TemplateIO(html=True) if no_event: r += htmltext('

') r += _('No events matching the filter.') r += htmltext('

') r += form.render() return r.getvalue() else: return self.filter_submitted(form, tags, remote_calendars) def filter_submitted(self, form, tags, remote_calendars): if remote_calendars: selected_remote_calendars = form.get_widget('calendars').parse() events = [] for remote_calendar in selected_remote_calendars: if remote_calendar == 'local': events.extend(Event.select()) else: try: events.extend(RemoteCalendar.get(remote_calendar).events) except KeyError: pass else: events = Event.select() events = [x for x in events if x.after_today()] if tags: selected_tags = Set(form.get_widget('tags').parse()) if selected_tags and len(selected_tags) != len(tags): events = [x for x in events if Set(x.keywords).intersection(selected_tags)] events.sort(lambda x,y: cmp(x.date_start, y.date_start)) r = TemplateIO(html=True) if len(events) > 1: r += htmltext('

') r += htmltext(_('%(nb)d events')) % {'nb': len(events)} r += htmltext('

') if events: r += htmltext('
') for ev in events: r += htmltext(ev.as_html_dt_dd()) r += htmltext('
') return r.getvalue() else: return self.filter(no_event=True)