django-cms-simple-events / simple_events / cms_plugins.py

from __future__ import with_statement
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from models import Event
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse

from calendar import LocaleHTMLCalendar, TimeEncoding, month_name, day_abbr
from datetime import date
from itertools import groupby

from django.utils.html import conditional_escape as esc

import locale

class EventCalendar(LocaleHTMLCalendar):
    """http://journal.uggedal.com/creating-a-flexible-monthly-calendar-in-django"""
    def __init__(self, events):
        super(EventCalendar, self).__init__()
        self.events = self.group_by_day(events)

    def formatmonthname(self, theyear, themonth, withyear=True):
        with TimeEncoding(self.locale) as encoding:
            # TODO: expand support for all years cases
            s = month_name[themonth]
            if themonth-1 == 0: # previous year
                p_s = '<a class="tipsy" title="%s" href="?month=%s&year=%s">&laquo;</a>' % (_("Previous Month"), 12, theyear-1)
            else:
                p_s = '<a class="tipsy" title="%s" href="?month=%s&year=%s">&laquo;</a>' % (_("Previous Month"), themonth-1, theyear)
            if themonth+1 == 13: # next year
                n_s = '<a class="tipsy" title="%s" href="?month=%s&year=%s">&raquo;</a>' % (_("Next Month"), 1, theyear+1)
            else:
                n_s = '<a class="tipsy" title="%s" href="?month=%s&year=%s">&raquo;</a>' % (_("Next Month"), themonth+1, theyear)
            if encoding is not None:
                s = s.decode(encoding)
            if withyear:
                s = '%s %s' % (s.capitalize(), theyear)
            return '<tr><th  class="monthyear" colspan="7">%s&nbsp;%s&nbsp;%s</tr>' % (p_s, s, n_s)


    def formatday(self, day, weekday):
        if day != 0:
            cssclass = self.cssclasses[weekday]
            if date.today() == date(self.year, self.month, day):
                cssclass += ' today'
                body = '<a class="tipsy" href="#" title="%s">%d</a>' % (_('Today'), day)
                if day in self.events:
                    d = reverse('events_day', args=(self.year, self.month, day))
                    body = '<a class="tipsy" href="%s" title="%s">%d</a>' % (d, _("Events found"), day)
                return self.day_cell(cssclass, body)

            if day in self.events:
                cssclass += ' filled'
                title = ['<ul class=event>']
                for event in self.events[day]:
                    title.append('<li><b>%s</b></li>' % esc(event.name))
                title.append('</ul>')
                d = reverse('events_day', args=(self.year, self.month, day))
                body = '<a class="tipsy" href="%s" title="%s">%d</a>' % (d, _("Events found"), day)
                return self.day_cell(cssclass, body)
            return self.day_cell(cssclass, day)
        return self.day_cell('noday', '&nbsp;')

    def formatweekday(self, day):
        oldlocale = locale.setlocale(locale.LC_TIME, self.locale)
        try:
            encoding = locale.getlocale(locale.LC_TIME)[1]
            s = day_abbr[day]
            if encoding is not None:
                s = s.decode(encoding)
            result = '<th class="weekday">%s</th>' % s
        finally:
            locale.setlocale(locale.LC_TIME, oldlocale)
        return result

    def formatmonth(self, year, month):
        self.year, self.month = year, month
        return super(EventCalendar, self).formatmonth(year, month)

    def group_by_day(self, events):
        field = lambda event: event.start.day
        return dict(
            [(day, list(items)) for day, items in groupby(events, field)]
        )

    def day_cell(self, cssclass, body):
        return '<td class="%s">%s</td>' % (cssclass, body)


class CMSCalendarEventsPlugin(CMSPluginBase):
    
    name = _("Calendar Events")
    render_template = "simple_events/events_calendar.html"

    def render(self, context, instance, placeholder):
        today = date.today()
        year = today.year
        month = today.month

        request = context['request']
        if request.GET:
            month = int(request.GET.get('month') or month)
            year = int(request.GET.get('year') or year)
        first_day = date(year,month,1)
        if month == 12:
            last_day = date(year+1,1,1)
        else:
            last_day = date(year,month+1,1)
        events = Event.objects.filter(start__gte=first_day).filter(start__lt=last_day)
        cal = EventCalendar(events).formatmonth(year, month)
        context.update({'instance':instance,
                        'events': events,
                        'calendar': mark_safe(cal),
                        'placeholder':placeholder})
        return context

plugin_pool.register_plugin(CMSCalendarEventsPlugin)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.