Initial implementation of a working ICalendarFeedView based on the Django syndication...
[philo.git] / contrib / julian / feedgenerator.py
1 from django.utils.feedgenerator import SyndicationFeed
2 import vobject
3
4
5 # Map the keys in the ICalendarFeed internal dictionary to the names of iCalendar attributes.
6 FEED_ICAL_MAP = {
7         'title': 'x-wr-calname',
8         'description': 'x-wr-caldesc',
9         #'link': ???,
10         #'language': ???,
11         #author_email
12         #author_name
13         #author_link
14         #subtitle
15         #categories
16         #feed_url
17         #feed_copyright
18         'id': 'prodid',
19         'ttl': 'x-published-ttl'
20 }
21
22
23 ITEM_ICAL_MAP = {
24         'title': 'summary',
25         'description': 'description',
26         'link': 'url',
27         # author_email, author_name, and author_link need special handling. Consider them the
28         # 'organizer' of the event <http://tools.ietf.org/html/rfc5545#section-3.8.4.3> and
29         # construct something based on that.
30         'pubdate': 'created',
31         'last_modified': 'last-modified',
32         #'comments' require special handling as well <http://tools.ietf.org/html/rfc5545#section-3.8.1.4>
33         'unique_id': 'uid',
34         'enclosure': 'attach', # does this need special handling?
35         'categories': 'categories', # does this need special handling?
36         # ttl is ignored.
37         'start': 'dtstart',
38         'end': 'dtend',
39 }
40
41
42 class ICalendarFeed(SyndicationFeed):
43         #def __init__(self, title, link, description, language=None, author_email=None,
44         #               author_name=None, author_link=None, subtitle=None, categories=None,
45         #               feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs):
46         #       super(ICalendarFeed, self).__init__(title, link, description, language,
47         #               author_email, author_name, author_link, subtitle, categories,
48         #               feed_url, feed_copyright, feed_guid, ttl, **kwargs)
49         #       
50         mime_type = 'text/calendar'
51         
52         def add_item(self, *args, **kwargs):
53                 for kwarg in ['start', 'end', 'last_modified', 'location']:
54                         kwargs.setdefault(kwarg, None)
55                 super(ICalendarFeed, self).add_item(*args, **kwargs)
56         
57         def write(self, outfile, encoding):
58                 # TODO: Use encoding... how? Just convert all values when setting them should work...
59                 cal = vobject.iCalendar()
60                 
61                 # IE/Outlook needs this. See
62                 # <http://blog.thescoop.org/archives/2007/07/31/django-ical-and-vobject/>
63                 cal.add('method').value = 'PUBLISH'
64                 
65                 for key, val in self.feed.items():
66                         if key in FEED_ICAL_MAP and val:
67                                 cal.add(FEED_ICAL_MAP[key]).value = val
68                 
69                 for item in self.items:
70                         # TODO: handle multiple types of events.
71                         event = cal.add('vevent')
72                         for key, val in item.items():
73                                 #TODO: handle the non-standard items like comments and author.
74                                 if key in ITEM_ICAL_MAP and val:
75                                         event.add(ITEM_ICAL_MAP[key]).value = val
76                 
77                 cal.serialize(outfile)