Initial implementation of a working ICalendarFeedView based on the Django syndication...
[philo.git] / contrib / julian / feedgenerator.py
diff --git a/contrib/julian/feedgenerator.py b/contrib/julian/feedgenerator.py
new file mode 100644 (file)
index 0000000..274f617
--- /dev/null
@@ -0,0 +1,77 @@
+from django.utils.feedgenerator import SyndicationFeed
+import vobject
+
+
+# Map the keys in the ICalendarFeed internal dictionary to the names of iCalendar attributes.
+FEED_ICAL_MAP = {
+       'title': 'x-wr-calname',
+       'description': 'x-wr-caldesc',
+       #'link': ???,
+       #'language': ???,
+       #author_email
+       #author_name
+       #author_link
+       #subtitle
+       #categories
+       #feed_url
+       #feed_copyright
+       'id': 'prodid',
+       'ttl': 'x-published-ttl'
+}
+
+
+ITEM_ICAL_MAP = {
+       'title': 'summary',
+       'description': 'description',
+       'link': 'url',
+       # author_email, author_name, and author_link need special handling. Consider them the
+       # 'organizer' of the event <http://tools.ietf.org/html/rfc5545#section-3.8.4.3> and
+       # construct something based on that.
+       'pubdate': 'created',
+       'last_modified': 'last-modified',
+       #'comments' require special handling as well <http://tools.ietf.org/html/rfc5545#section-3.8.1.4>
+       'unique_id': 'uid',
+       'enclosure': 'attach', # does this need special handling?
+       'categories': 'categories', # does this need special handling?
+       # ttl is ignored.
+       'start': 'dtstart',
+       'end': 'dtend',
+}
+
+
+class ICalendarFeed(SyndicationFeed):
+       #def __init__(self, title, link, description, language=None, author_email=None,
+       #               author_name=None, author_link=None, subtitle=None, categories=None,
+       #               feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs):
+       #       super(ICalendarFeed, self).__init__(title, link, description, language,
+       #               author_email, author_name, author_link, subtitle, categories,
+       #               feed_url, feed_copyright, feed_guid, ttl, **kwargs)
+       #       
+       mime_type = 'text/calendar'
+       
+       def add_item(self, *args, **kwargs):
+               for kwarg in ['start', 'end', 'last_modified', 'location']:
+                       kwargs.setdefault(kwarg, None)
+               super(ICalendarFeed, self).add_item(*args, **kwargs)
+       
+       def write(self, outfile, encoding):
+               # TODO: Use encoding... how? Just convert all values when setting them should work...
+               cal = vobject.iCalendar()
+               
+               # IE/Outlook needs this. See
+               # <http://blog.thescoop.org/archives/2007/07/31/django-ical-and-vobject/>
+               cal.add('method').value = 'PUBLISH'
+               
+               for key, val in self.feed.items():
+                       if key in FEED_ICAL_MAP and val:
+                               cal.add(FEED_ICAL_MAP[key]).value = val
+               
+               for item in self.items:
+                       # TODO: handle multiple types of events.
+                       event = cal.add('vevent')
+                       for key, val in item.items():
+                               #TODO: handle the non-standard items like comments and author.
+                               if key in ITEM_ICAL_MAP and val:
+                                       event.add(ITEM_ICAL_MAP[key]).value = val
+               
+               cal.serialize(outfile)
\ No newline at end of file