1.1 --- a/imip_manager.py Sat Jan 31 02:17:37 2015 +0100
1.2 +++ b/imip_manager.py Sat Jan 31 02:18:03 2015 +0100
1.3 @@ -112,25 +112,32 @@
1.4 self.user = user
1.5 self.messenger = messenger
1.6
1.7 - self.organisers = map(get_address, self.get_values("ORGANIZER"))
1.8 + self.organiser = self.get_value("ORGANIZER")
1.9 + self.attendees = self.get_values("ATTENDEE")
1.10
1.11 # Communication methods.
1.12
1.13 - def send_message(self, sender):
1.14 + def send_message(self, method, sender):
1.15
1.16 """
1.17 - Create a full calendar object and send it to the organisers, sending a
1.18 - copy to the 'sender'.
1.19 + Create a full calendar object employing the given 'method', and send it
1.20 + to the appropriate recipients, also sending a copy to the 'sender'.
1.21 """
1.22
1.23 node = to_node(self.obj)
1.24 - part = to_part("REPLY", [node])
1.25 - message = self.messenger.make_outgoing_message([part], self.organisers, outgoing_bcc=sender)
1.26 - self.messenger.sendmail(self.organisers, message.as_string(), outgoing_bcc=sender)
1.27 + part = to_part(method, [node])
1.28 +
1.29 + if self.user == self.organiser:
1.30 + recipients = map(get_address, self.attendees)
1.31 + else:
1.32 + recipients = [get_address(self.organiser)]
1.33 +
1.34 + message = self.messenger.make_outgoing_message([part], recipients, outgoing_bcc=sender)
1.35 + self.messenger.sendmail(recipients, message.as_string(), outgoing_bcc=sender)
1.36
1.37 # Action methods.
1.38
1.39 - def process_request(self, accept, update=False):
1.40 + def process_received_request(self, accept, update=False):
1.41
1.42 """
1.43 Process the current request for the given 'user', accepting any request
1.44 @@ -147,8 +154,6 @@
1.45 for attendee, attendee_attr in self.get_items("ATTENDEE"):
1.46
1.47 if attendee == self.user:
1.48 - freebusy = self.store.get_freebusy(attendee)
1.49 -
1.50 attendee_attr["PARTSTAT"] = accept and "ACCEPTED" or "DECLINED"
1.51 if self.messenger and self.messenger.sender != get_address(attendee):
1.52 attendee_attr["SENT-BY"] = get_uri(self.messenger.sender)
1.53 @@ -158,12 +163,31 @@
1.54 self.details["SEQUENCE"] = [(str(int(sequence) + 1), {})]
1.55 self.update_dtstamp()
1.56
1.57 - self.send_message(get_address(attendee))
1.58 + self.send_message("REPLY", get_address(attendee))
1.59
1.60 return True
1.61
1.62 return False
1.63
1.64 + def process_created_request(self, update=False):
1.65 +
1.66 + """
1.67 + Process the current request for the given 'user', sending a created
1.68 + request to attendees. Return whether any action was taken.
1.69 +
1.70 + If 'update' is given, the sequence number will be incremented in order
1.71 + to override any previous message.
1.72 + """
1.73 +
1.74 + if update:
1.75 + sequence = self.get_value("SEQUENCE") or "0"
1.76 + self.details["SEQUENCE"] = [(str(int(sequence) + 1), {})]
1.77 + self.update_dtstamp()
1.78 +
1.79 + self.send_message("REQUEST", get_address(self.organiser))
1.80 +
1.81 + return True
1.82 +
1.83 class Manager:
1.84
1.85 "A simple manager application."
1.86 @@ -293,7 +317,10 @@
1.87
1.88 def handle_newevent(self):
1.89
1.90 - "Handle any new event operation."
1.91 + """
1.92 + Handle any new event operation, creating a new event and redirecting to
1.93 + the event page for further activity.
1.94 + """
1.95
1.96 # Handle a submitted form.
1.97
1.98 @@ -330,8 +357,8 @@
1.99 rwrite(("UID", {}, uid))
1.100 rwrite(("SUMMARY", {}, "New event at %s" % utcnow))
1.101 rwrite(("DTSTAMP", {}, utcnow))
1.102 - rwrite(("DTSTART", {"VALUE" : "DATE-TIME"}, start))
1.103 - rwrite(("DTEND", {"VALUE" : "DATE-TIME"}, end or
1.104 + rwrite(("DTSTART", {"VALUE" : "DATE-TIME", "TZID" : tzid}, start))
1.105 + rwrite(("DTEND", {"VALUE" : "DATE-TIME", "TZID" : tzid}, end or
1.106 format_datetime(get_end_of_day(get_datetime(start, {"TZID" : tzid})))
1.107 ))
1.108 rwrite(("ORGANIZER", {}, self.user))
1.109 @@ -367,19 +394,21 @@
1.110
1.111 accept = args.has_key("accept")
1.112 decline = args.has_key("decline")
1.113 + invite = args.has_key("invite")
1.114 update = not queued and args.has_key("update")
1.115
1.116 - if accept or decline:
1.117 + if accept or decline or invite:
1.118
1.119 handler = ManagerHandler(request, self.user, self.messenger)
1.120
1.121 - if handler.process_request(accept, update):
1.122 + # Process the request and remove it from the list.
1.123
1.124 - # Remove the request from the list.
1.125 + if (accept or decline) and handler.process_received_request(accept, update) or \
1.126 + invite and handler.process_created_request(update):
1.127
1.128 self.remove_request(uid)
1.129
1.130 - elif args.has_key("ignore"):
1.131 + elif args.has_key("discard"):
1.132
1.133 # Remove the request from the list.
1.134
1.135 @@ -402,17 +431,20 @@
1.136
1.137 details = self._get_details(obj)
1.138
1.139 - attendees = get_value_map(details, "ATTENDEE")
1.140 - attendee_attr = attendees.get(self.user)
1.141 + is_organiser = get_value(details, "ORGANIZER") == self.user
1.142 +
1.143 + if not is_organiser:
1.144 + attendees = get_value_map(details, "ATTENDEE")
1.145 + attendee_attr = attendees.get(self.user)
1.146
1.147 - if attendee_attr:
1.148 - partstat = attendee_attr.get("PARTSTAT")
1.149 - if partstat == "ACCEPTED":
1.150 - self.page.p("This request has been accepted.")
1.151 - elif partstat == "DECLINED":
1.152 - self.page.p("This request has been declined.")
1.153 - else:
1.154 - self.page.p("This request has been ignored.")
1.155 + if attendee_attr:
1.156 + partstat = attendee_attr.get("PARTSTAT")
1.157 + if partstat == "ACCEPTED":
1.158 + self.page.p("This request has been accepted.")
1.159 + elif partstat == "DECLINED":
1.160 + self.page.p("This request has been declined.")
1.161 + else:
1.162 + self.page.p("This request has not yet been dealt with.")
1.163
1.164 if needs_action:
1.165 self.page.p("An action is required for this request:")
1.166 @@ -421,13 +453,24 @@
1.167
1.168 self.page.form(method="POST")
1.169 self.page.p()
1.170 - self.page.input(name="accept", type="submit", value="Accept")
1.171 +
1.172 + # Show appropriate options depending on the role of the user.
1.173 +
1.174 + if is_organiser:
1.175 + self.page.input(name="invite", type="submit", value="Invite")
1.176 + else:
1.177 + self.page.input(name="accept", type="submit", value="Accept")
1.178 + self.page.add(" ")
1.179 + self.page.input(name="decline", type="submit", value="Decline")
1.180 +
1.181 self.page.add(" ")
1.182 - self.page.input(name="decline", type="submit", value="Decline")
1.183 - self.page.add(" ")
1.184 - self.page.input(name="ignore", type="submit", value="Ignore")
1.185 + self.page.input(name="discard", type="submit", value="Discard")
1.186 +
1.187 + # Updated objects need to have details updated upon sending.
1.188 +
1.189 if not needs_action:
1.190 self.page.input(name="update", type="hidden", value="true")
1.191 +
1.192 self.page.p.close()
1.193 self.page.form.close()
1.194