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