diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | public/js/calendar.js | 7 | ||||
-rw-r--r-- | scripts/calendar_plugin.py | 47 | ||||
-rw-r--r-- | scripts/get_calendar.py | 87 | ||||
-rw-r--r-- | scripts/template.conf | 1 | ||||
-rw-r--r-- | template/calendar.j2 | 13 | ||||
-rw-r--r-- | template/template/template.html | 1 |
7 files changed, 157 insertions, 0 deletions
@@ -4,3 +4,4 @@ /public/css/*.status.css /public/api *~ +/template/calendar.json diff --git a/public/js/calendar.js b/public/js/calendar.js new file mode 100644 index 0000000..2f402ae --- /dev/null +++ b/public/js/calendar.js @@ -0,0 +1,7 @@ +$(function() { + $('.calendar-listing>p').click(function() { + $(this).next().toggle('fast'); + return false; + }).next().hide(); +}); + diff --git a/scripts/calendar_plugin.py b/scripts/calendar_plugin.py new file mode 100644 index 0000000..fdc1283 --- /dev/null +++ b/scripts/calendar_plugin.py @@ -0,0 +1,47 @@ +import template +import plugin +import string +import os + +import locale +from datetime import datetime,timedelta +import jinja2 +import json + +class CalendarPlugin: + def __init__(self): + calpath = os.path.join(template.path, 'calendar.json') + with open(calpath, 'r') as calfile: + events = json.load(calfile) + for event in events: + event['start'] = datetime.strptime(event['start'], '%Y-%m-%dT%H:%M:%S') + event['end'] = datetime.strptime(event['end'], '%Y-%m-%dT%H:%M:%S') + event['multiday'] = (event['end'] - event['start']) > timedelta(days=1) + self.events = sorted(events, key=lambda x:x['start']) + template_loader = jinja2.FileSystemLoader(searchpath=os.path.join(template.path)) + self.template_env = jinja2.Environment(loader=template_loader) + locale.setlocale(locale.LC_ALL, 'de_DE.UTF-8') + + def _get_calendar(self): + return self.template_env.get_template('calendar.j2').render({ + 'events': self.events, + 'class': 'calendar-main' + }).encode('utf-8') + + def _get_calendar_head(self): + return self.template_env.get_template('calendar.j2').render({ + 'events': self.events[:4], + 'class': 'calendar-head' + }).encode('utf-8') + + def process_content(self, page_content): + return_value = {} + for filename, content in page_content.iteritems(): + t = string.Template(content) + return_value[filename] = t.safe_substitute( + calendar = self._get_calendar(), + calendar_head = self._get_calendar_head() + ) + return return_value + +plugin.plugin_manager.register(CalendarPlugin()) diff --git a/scripts/get_calendar.py b/scripts/get_calendar.py new file mode 100644 index 0000000..3e0f8e3 --- /dev/null +++ b/scripts/get_calendar.py @@ -0,0 +1,87 @@ +from datetime import datetime, timedelta, time +from dateutil.relativedelta import relativedelta +import urllib2 + +import json +import logging +import sys +import copy +import os + +from dateutil.rrule import rrulestr +import icalendar + +def fetch_calendar(logger): + """Fetches the calendar events and returns a icalendar.Calendar instance. + """ + response = urllib2.urlopen(CALENDARIUM_IMPORT_URL) + logger.debug('Fetched calendar from %s' % CALENDARIUM_IMPORT_URL) + return icalendar.Calendar.from_ical(response.read()) + +def get_events(calendar, after, before): + """Yields all events in calendar as dictionary. + + Only events after (including) after will be shown. Recurring events + til before (inclusively) will be shown. + """ + for event in calendar.walk('vevent'): + event_fields = [ + # dest, src, default + ('name', 'summary', 'unknown Event'), + ('description', 'description', ''), + ] + event_info = {} + for fieldinfo in event_fields: + try: + event_info[fieldinfo[0]] = event[fieldinfo[1]].format().encode("utf-8") + event_info[fieldinfo[0]] = event_info[fieldinfo[0]].decode("string-escape") + except KeyError: + event_info[fieldinfo[0]] = fieldinfo[2] + start = icalendar.vDDDTypes.from_ical(event['dtstart'].to_ical()) + if 'dtend' in event: + end = icalendar.vDDDTypes.from_ical(event['dtend'].to_ical()) + else: + end = start + icalendar.vDDDTypes.from_ical(event['duration'].to_ical()) + if not isinstance(start, datetime): + start = datetime.combine(start, time()) + if not isinstance(end, datetime): + end = datetime.combine(end, time()) + + if 'rrule' in event: + rrule = rrulestr(event['rrule'].to_ical(), dtstart=start) + duration = end - start + for occurence in rrule.between(after, before, True): + event_info['start'] = occurence + event_info['end'] = occurence + duration + yield copy.deepcopy(event_info) + else: + if start >= after: + event_info['start'] = start + event_info['end'] = end + yield event_info + +class DatetimeEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, datetime): + return obj.isoformat() + return json.JSONEncoder.default(self,obj) + +#CALENDARIUM_IMPORT_URL = 'https://sublab.org:5232/calendars/events' +CALENDARIUM_IMPORT_URL = 'https://posteo.de/calendars/ics/ruku1tibpa2b2evfwsxrbvwcy2n60j9g' +if __name__ == '__main__': + logging.basicConfig(stream=sys.stderr, level=logging.ERROR) + logger = logging.getLogger('calendar_feed') + calendar = fetch_calendar(logger) + now = datetime.now() + after = now - relativedelta(days=1) + before = now + relativedelta(months=+1) + + events = [] + for event in get_events(calendar, after, before): + event['start'] = event['start'].isoformat() + event['end'] = event['end'].isoformat() + events.append(event) + destination = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../template/calendar.json') + with open(destination + '.new', 'w') as dfile: + dfile.write(json.dumps(events, indent=4)) + os.rename(destination + '.new', destination) diff --git a/scripts/template.conf b/scripts/template.conf index 2f9ee42..105f94a 100644 --- a/scripts/template.conf +++ b/scripts/template.conf @@ -7,4 +7,5 @@ path = ../template target = ../public/ [Plugins] +calendar_plugin=load news=load diff --git a/template/calendar.j2 b/template/calendar.j2 new file mode 100644 index 0000000..0e5a10c --- /dev/null +++ b/template/calendar.j2 @@ -0,0 +1,13 @@ +<div class="calendar-listing {{ class }}"> +{%- for event in events %} + <p><span class="date"> + {%- if event.multiday %} + {{- event.start.strftime('%d. %B %Y').decode('utf-8') }} - {{ event.end.strftime('%d. %B %Y').decode('utf-8') }} + {%- else %}{{ event.start.strftime('%d. %B %Y, %H:%M Uhr').decode('utf-8') }} + {%- endif -%} + </span><span class="name">{{ event.name }}</span></p> + <div> + <p>{{ event.description|default('Keine Beschreibung',true) }}</p> + </div> +{%- endfor %} +</div> diff --git a/template/template/template.html b/template/template/template.html index f483f79..37985cd 100644 --- a/template/template/template.html +++ b/template/template/template.html @@ -25,6 +25,7 @@ <link rel="space-api" href="/status.json" /> <script src="/js/jquery.min.js"></script> + <script src="/js/calendar.js"></script> <script src="/js/bootstrap.min.js"></script> </head> |