Generated: Tue 2013-04-16 13:15 CEST
Source file: /home/tobi/Projects/calendarium/src/calendarium/views.py
Stats: 178 executed, 6 missed, 13 excluded, 104 ignored
"""Views for the ``calendarium`` app."""import calendarfrom dateutil.relativedelta import relativedeltafrom django.contrib.auth.decorators import permission_requiredfrom django.core.urlresolvers import reversefrom django.forms.models import model_to_dictfrom django.http import Http404, HttpResponseRedirectfrom django.utils.decorators import method_decoratorfrom django.utils.timezone import datetime, now, timedelta, utcfrom django.views.generic import ( CreateView, DeleteView, DetailView, RedirectView, TemplateView, UpdateView,)from .constants import OCCURRENCE_DECISIONSfrom .forms import OccurrenceFormfrom .models import EventCategory, Event, Occurrencefrom .utils import monday_of_weekclass CategoryMixin(object): """Mixin to handle category filtering.""" def dispatch(self, request, *args, **kwargs): if request.GET.get('category'): try: category_id = int(request.GET.get('category')) except ValueError: pass else: try: self.category = EventCategory.objects.get(pk=category_id) except EventCategory.DoesNotExist: pass return super(CategoryMixin, self).dispatch(request, *args, **kwargs) def get_category_context(self, **kwargs): context = {'categories': EventCategory.objects.all()} if hasattr(self, 'category'): context.update({'current_category': self.category}) return contextclass CalendariumRedirectView(RedirectView): """View to redirect to the current month view.""" def get_redirect_url(self, **kwargs): return reverse('calendar_month', kwargs={'year': now().year, 'month': now().month})class MonthView(CategoryMixin, TemplateView): """View to return all occurrences of an event for a whole month.""" template_name = 'calendarium/calendar_month.html' def dispatch(self, request, *args, **kwargs): self.month = int(kwargs.get('month')) self.year = int(kwargs.get('year')) if self.month not in range(1, 13): raise Http404 if request.method == 'POST': if request.POST.get('next'): new_date = datetime(self.year, self.month, 1) + timedelta( days=31) return HttpResponseRedirect(reverse('calendar_month', kwargs={ 'year': new_date.year, 'month': new_date.month})) elif request.POST.get('previous'): new_date = datetime(self.year, self.month, 1) - timedelta( days=1) return HttpResponseRedirect(reverse('calendar_month', kwargs={ 'year': new_date.year, 'month': new_date.month})) elif request.POST.get('today'): return HttpResponseRedirect(reverse('calendar_month', kwargs={ 'year': now().year, 'month': now().month})) if request.is_ajax(): self.template_name = 'calendarium/partials/calendar_month.html' return super(MonthView, self).dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): ctx = self.get_category_context() month = [[]] week = 0 start = datetime(year=self.year, month=self.month, day=1, tzinfo=utc) end = datetime( year=self.year, month=self.month, day=1, tzinfo=utc ) + relativedelta(months=1) all_occurrences = Event.objects.get_occurrences( start, end, ctx.get('current_category')) for day in calendar.Calendar().itermonthdays(self.year, self.month): current = False if day: date = datetime(year=self.year, month=self.month, day=day, tzinfo=utc) occurrences = filter( lambda occ, date=date: occ.start.replace( hour=0, minute=0, second=0, microsecond=0) == date, all_occurrences) if date.date() == now().date(): current = True else: occurrences = [] month[week].append((day, occurrences, current)) if len(month[week]) == 7: month.append([]) week += 1 ctx.update({'month': month, 'date': date}) return ctxclass WeekView(CategoryMixin, TemplateView): """View to return all occurrences of an event for one week.""" template_name = 'calendarium/calendar_week.html' def dispatch(self, request, *args, **kwargs): self.week = int(kwargs.get('week')) self.year = int(kwargs.get('year')) if self.week not in range(1, 53): raise Http404 if request.method == 'POST': if request.POST.get('next'): date = monday_of_week(self.year, self.week) + timedelta(days=7) return HttpResponseRedirect(reverse('calendar_week', kwargs={ 'year': date.year, 'week': date.date().isocalendar()[1]})) elif request.POST.get('previous'): date = monday_of_week(self.year, self.week) - timedelta(days=7) return HttpResponseRedirect(reverse('calendar_week', kwargs={ 'year': date.year, 'week': date.date().isocalendar()[1]})) elif request.POST.get('today'): return HttpResponseRedirect(reverse('calendar_week', kwargs={ 'year': now().year, 'week': now().date().isocalendar()[1]})) if request.is_ajax(): self.template_name = 'calendarium/partials/calendar_week.html' return super(WeekView, self).dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): ctx = self.get_category_context() date = monday_of_week(self.year, self.week) week = [] day = 0 start = date end = date + relativedelta(days=7) all_occurrences = Event.objects.get_occurrences( start, end, ctx.get('current_category')) while day < 7: current = False occurrences = filter( lambda occ, date=date: occ.start.replace( hour=0, minute=0, second=0, microsecond=0) == date, all_occurrences) if date.date() == now().date(): current = True week.append((date, occurrences, current)) day += 1 date = date + timedelta(days=1) ctx.update({'week': week, 'date': date, 'week_nr': self.week}) return ctxclass DayView(CategoryMixin, TemplateView): """View to return all occurrences of an event for one day.""" template_name = 'calendarium/calendar_day.html' def dispatch(self, request, *args, **kwargs): self.day = int(kwargs.get('day')) self.month = int(kwargs.get('month')) self.year = int(kwargs.get('year')) try: self.date = datetime(year=self.year, month=self.month, day=self.day, tzinfo=utc) except ValueError: raise Http404 if request.method == 'POST': if request.POST.get('next'): date = self.date + timedelta(days=1) return HttpResponseRedirect(reverse('calendar_day', kwargs={ 'year': date.year, 'month': date.month, 'day': date.day})) elif request.POST.get('previous'): date = self.date - timedelta(days=1) return HttpResponseRedirect(reverse('calendar_day', kwargs={ 'year': date.year, 'month': date.month, 'day': date.day})) elif request.POST.get('today'): return HttpResponseRedirect(reverse('calendar_day', kwargs={ 'year': now().year, 'month': now().month, 'day': now().day})) if request.is_ajax(): self.template_name = 'calendarium/partials/calendar_day.html' return super(DayView, self).dispatch(request, *args, **kwargs) def get_context_data(self, **kwargs): ctx = self.get_category_context() occurrences = Event.objects.get_occurrences( self.date, self.date, ctx.get('current_category')) ctx.update({'date': self.date, 'occurrences': occurrences}) return ctxclass EventDetailView(DetailView): """View to return information of an event.""" model = Eventclass EventMixin(object): """Mixin to handle event-related functions.""" model = Event @method_decorator(permission_required('calendarium.add_event')) def dispatch(self, request, *args, **kwargs): return super(EventMixin, self).dispatch(request, *args, **kwargs)class EventUpdateView(EventMixin, UpdateView): """View to update information of an event.""" passclass EventCreateView(EventMixin, CreateView): """View to create an event.""" passclass EventDeleteView(EventMixin, DeleteView): """View to delete an event.""" passclass OccurrenceViewMixin(object): """Mixin to avoid repeating code for the Occurrence view classes.""" form_class = OccurrenceForm def dispatch(self, request, *args, **kwargs): try: self.event = Event.objects.get(pk=kwargs.get('pk')) except Event.DoesNotExist: raise Http404 year = int(kwargs.get('year')) month = int(kwargs.get('month')) day = int(kwargs.get('day')) try: date = datetime(year, month, day, tzinfo=utc) except TypeError: raise Http404 # this should retrieve the one single occurrence, that has a # matching start date try: occ = Occurrence.objects.get( start__year=year, start__month=month, start__day=day) except Occurrence.DoesNotExist: occ_gen = self.event.get_occurrences(self.event.start) occ = occ_gen.next() while occ.start.date() < date.date(): occ = occ_gen.next() if occ.start.date() == date.date(): self.occurrence = occ else: raise Http404 self.object = self.occurrence return super(OccurrenceViewMixin, self).dispatch( request, *args, **kwargs) def get_object(self): return self.occurrence def get_form_kwargs(self): kwargs = super(OccurrenceViewMixin, self).get_form_kwargs() kwargs.update({'initial': model_to_dict(self.occurrence)}) return kwargsclass OccurrenceDeleteView(OccurrenceViewMixin, DeleteView): """View to delete an occurrence of an event.""" def delete(self, request, *args, **kwargs): self.object = self.get_object() decision = self.request.POST.get('decision') self.object.delete_period(decision) return HttpResponseRedirect(self.get_success_url()) def get_context_data(self, object): ctx = super(OccurrenceDeleteView, self).get_context_data() ctx.update({ 'decisions': OCCURRENCE_DECISIONS, 'object': self.object }) return ctx def get_success_url(self): return reverse('calendar_current_month')class OccurrenceDetailView(OccurrenceViewMixin, DetailView): """View to show information of an occurrence of an event.""" passclass OccurrenceUpdateView(OccurrenceViewMixin, UpdateView): """View to edit an occurrence of an event.""" pass