summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--public/js/calendar.js7
-rw-r--r--scripts/calendar_plugin.py47
-rw-r--r--scripts/get_calendar.py87
-rw-r--r--scripts/template.conf1
-rw-r--r--template/calendar.j213
-rw-r--r--template/template/template.html1
7 files changed, 157 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e86cdd6..d202ce7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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>