1 #!/usr/bin/env python 2 3 """ 4 Handlers for a person for whom scheduling is performed. 5 """ 6 7 from email.mime.text import MIMEText 8 from imiptools.content import Handler, to_part 9 from vCalendar import to_node 10 11 class Event(Handler): 12 13 "An event handler." 14 15 def add(self): 16 pass 17 18 def cancel(self): 19 pass 20 21 def counter(self): 22 23 "Since this handler does not send requests, it will not handle replies." 24 25 pass 26 27 def declinecounter(self): 28 29 """ 30 Since this handler does not send counter proposals, it will not handle 31 replies to such proposals. 32 """ 33 34 pass 35 36 def publish(self): 37 pass 38 39 def refresh(self): 40 pass 41 42 def reply(self): 43 44 "Since this handler does not send requests, it will not handle replies." 45 46 pass 47 48 def request(self): 49 50 "Hold requests and notify the recipient." 51 52 oa = self.require_organiser_and_attendees() 53 if not oa: 54 return None 55 56 (organiser, organiser_attr), attendees = oa 57 58 # Process each attendee separately. 59 60 for attendee, attendee_attr in attendees.items(): 61 62 if not self.have_new_object(attendee, "VEVENT"): 63 continue 64 65 # Store the event and queue the request. 66 67 self.store.set_event(attendee, self.uid, to_node( 68 {"VEVENT" : [(self.details, {})]} 69 )) 70 71 self.store.queue_request(attendee, self.uid) 72 73 # The message is now wrapped and passed on to the recipient. 74 75 return "REQUEST", MIMEText("A request has been queued.") 76 77 class Freebusy(Handler): 78 79 "A free/busy handler." 80 81 def publish(self): 82 pass 83 84 def reply(self): 85 86 "Since this handler does not send requests, it will not handle replies." 87 88 pass 89 90 def request(self): 91 92 """ 93 Respond to a request by preparing a reply containing free/busy 94 information for each indicated attendee. 95 """ 96 97 # NOTE: This is currently the same as the resource handler but should be 98 # NOTE: subject to policy/preferences. 99 100 oa = self.require_organiser_and_attendees() 101 if not oa: 102 return None 103 104 (organiser, organiser_attr), attendees = oa 105 106 # Construct an appropriate fragment. 107 108 calendar = [] 109 cwrite = calendar.append 110 111 # Get the details for each attendee. 112 113 for attendee, attendee_attr in attendees.items(): 114 freebusy = self.store.get_freebusy(attendee) 115 116 record = [] 117 rwrite = record.append 118 119 rwrite(("ORGANIZER", organiser_attr, organiser)) 120 rwrite(("ATTENDEE", attendee_attr, attendee)) 121 rwrite(("UID", {}, self.uid)) 122 123 if freebusy: 124 for start, end, uid in freebusy: 125 rwrite(("FREEBUSY", {"FBTYPE" : "BUSY"}, [start, end])) 126 127 cwrite(("VFREEBUSY", {}, record)) 128 129 # Return the reply. 130 131 return "REPLY", to_part("REPLY", calendar) 132 133 class Journal(Handler): 134 135 "A journal entry handler." 136 137 def add(self): 138 pass 139 140 def cancel(self): 141 pass 142 143 def publish(self): 144 pass 145 146 class Todo(Handler): 147 148 "A to-do item handler." 149 150 def add(self): 151 pass 152 153 def cancel(self): 154 pass 155 156 def counter(self): 157 158 "Since this handler does not send requests, it will not handle replies." 159 160 pass 161 162 def declinecounter(self): 163 164 """ 165 Since this handler does not send counter proposals, it will not handle 166 replies to such proposals. 167 """ 168 169 pass 170 171 def publish(self): 172 pass 173 174 def refresh(self): 175 pass 176 177 def reply(self): 178 179 "Since this handler does not send requests, it will not handle replies." 180 181 pass 182 183 def request(self): 184 pass 185 186 # Handler registry. 187 188 handlers = [ 189 ("VFREEBUSY", Freebusy), 190 ("VEVENT", Event), 191 ("VTODO", Todo), 192 ("VJOURNAL", Journal), 193 ] 194 195 # vim: tabstop=4 expandtab shiftwidth=4