summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exchange/commands.py116
1 files changed, 108 insertions, 8 deletions
diff --git a/exchange/commands.py b/exchange/commands.py
index b1169e2..9c72a3e 100644
--- a/exchange/commands.py
+++ b/exchange/commands.py
@@ -12,18 +12,70 @@ development code but it does the trick. Watch out, it doesn't consider
12many corner cases. 12many corner cases.
13""" 13"""
14 14
15import re
16
15import dateutil.parser as date_parser 17import dateutil.parser as date_parser
16import xml.etree.cElementTree as ElementTree 18import xml.etree.cElementTree as ElementTree
17 19
18from string import Template 20from string import Template
19from httplib import HTTPSConnection 21from httplib import HTTPSConnection
20from datetime import datetime, timedelta 22from datetime import datetime, timedelta, date, tzinfo
21from exchange import ExchangeException, EST 23from exchange import ExchangeException, EST
22from icalendar import Calendar, Event as _Event 24from icalendar import Calendar, Event as _Event, Alarm
25from icalendar import vCalAddress, vText
26
27
28class InvalidEventError(Exception):
29 pass
30
31
32class Organizer(object):
33
34 def __init__(self, cn, email):
35 self.cn = cn
36 self.email = email
37
38 def __repr__(self):
39 return u"vCalAddress(%s)" % str.__repr__(self)
40
41 def ical(self):
42 return "CN=%s:%s" % (self.cn, self.email)
43
44 def __str__(self):
45 return self.ical()
46
47
48class EST(tzinfo):
49
50 def tzname(self, dt):
51 return "EST"
52
53 def utcoffset(self, dt):
54 return timedelta(0)
55
56 dst = utcoffset
57
58
59class EmailParser(object):
60
61 EXCHANGE_FORMAT = re.compile("([^<]*)<([^>]*)>")
62
63 def parse(self, email):
64 if not email:
65 return
66
67 match = self.EXCHANGE_FORMAT.match(email)
68 if match:
69 return match.groups()
23 70
24 71
25class Event(_Event): 72class Event(_Event):
26 73
74 def __init__(self):
75 super(Event, self).__init__()
76 self.start_date = None
77 self.end_date = None
78
27 def _get_element_text(self, element, key): 79 def _get_element_text(self, element, key):
28 value = element.find(key) 80 value = element.find(key)
29 81
@@ -36,11 +88,53 @@ class Event(_Event):
36 add_as = key if not add_as else add_as 88 add_as = key if not add_as else add_as
37 self.add(add_as, value) 89 self.add(add_as, value)
38 90
91 def add_organizer(self, element):
92 value = self._get_element_text(element, 'organizer')
93
94 parsed = EmailParser().parse(value)
95 if not parsed:
96 return
97
98 name = parsed[0].strip().strip('"')
99
100 organizer = vCalAddress('MAILTO:%s' % parsed[1])
101 organizer.params['cn'] = vText(name)
102 organizer.params['ROLE'] = vText('CHAIR')
103
104 self.add('organizer', organizer, encode=0)
105
39 def add_date(self, element, key, add_as=None): 106 def add_date(self, element, key, add_as=None):
40 value = date_parser.parse(self._get_element_text(element, key)) 107 value = date_parser.parse(self._get_element_text(element, key))
41 108
42 add_as = key if not add_as else add_as 109 if key == 'start_date':
43 self.add(add_as, value) 110 self.start_date = value
111 elif key == 'end_date':
112 self.end_date = value
113 else:
114 add_as = key if not add_as else add_as
115 self.add(add_as, value)
116
117 def finalize(self):
118 if not self.start_date and self.end_date:
119 raise InvalidEventError()
120
121 delta = self.end_date - self.start_date
122 if delta.days > 1:
123 start_date = date(self.start_date.year, self.start_date.month, self.start_date.day)
124 end_date = date(self.end_date.year, self.end_date.month, self.end_date.day)
125 else:
126 start_date = self.start_date
127 end_date = self.end_date
128
129 if self.start_date > datetime.now(tz=EST()):
130 alarm = Alarm()
131 alarm.add("action", "DISPLAY")
132 alarm.add("description", "REMINDER")
133 alarm.add("trigger", timedelta(minutes=-15))
134 self.add_component(alarm)
135
136 self.add('dtstart', start_date)
137 self.add('dtend', end_date)
44 138
45 139
46class ExchangeRequest(object): 140class ExchangeRequest(object):
@@ -152,10 +246,16 @@ class FetchCalendar(ExchangeCommand):
152 event = Event() 246 event = Event()
153 event.add_text(item, 'subject', add_as='summary') 247 event.add_text(item, 'subject', add_as='summary')
154 event.add_text(item, 'location') 248 event.add_text(item, 'location')
249 event.add_text(item, 'status')
155 event.add_text(item, 'description') 250 event.add_text(item, 'description')
156 event.add_date(item, 'start_date', add_as='dtstart') 251 event.add_date(item, 'start_date')
157 event.add_date(item, 'end_date', add_as='dtend') 252 event.add_date(item, 'end_date')
158 253 event.add_organizer(item)
159 calendar.add_component(event) 254
255 try:
256 event.finalize()
257 calendar.add_component(event)
258 except InvalidEventError:
259 print "Rejected event"
160 260
161 return calendar 261 return calendar