1.1 --- a/imip_manager.py Tue Feb 10 19:01:12 2015 +0100
1.2 +++ b/imip_manager.py Tue Feb 10 19:10:57 2015 +0100
1.3 @@ -229,7 +229,7 @@
1.4
1.5 return False
1.6
1.7 - def process_created_request(self, method, update=False, removed=None):
1.8 + def process_created_request(self, method, update=False, removed=None, added=None):
1.9
1.10 """
1.11 Process the current request for the given 'user', sending a created
1.12 @@ -241,6 +241,8 @@
1.13
1.14 If 'removed' is specified, a list of participants to be removed is
1.15 provided.
1.16 +
1.17 + If 'added' is specified, a list of participants to be added is provided.
1.18 """
1.19
1.20 organiser, organiser_attr = uri_item(self.obj.get_item("ORGANIZER"))
1.21 @@ -250,17 +252,25 @@
1.22
1.23 to_cancel = []
1.24
1.25 - if removed:
1.26 + if added or removed:
1.27 attendees = uri_items(self.obj.get_items("ATTENDEE"))
1.28 - remaining = []
1.29 +
1.30 + if removed:
1.31 + remaining = []
1.32
1.33 - for attendee, attendee_attr in attendees:
1.34 - if attendee in removed:
1.35 - to_cancel.append((attendee, attendee_attr))
1.36 - else:
1.37 - remaining.append((attendee, attendee_attr))
1.38 + for attendee, attendee_attr in attendees:
1.39 + if attendee in removed:
1.40 + to_cancel.append((attendee, attendee_attr))
1.41 + else:
1.42 + remaining.append((attendee, attendee_attr))
1.43
1.44 - self.obj["ATTENDEE"] = remaining
1.45 + attendees = remaining
1.46 +
1.47 + if added:
1.48 + for attendee in added:
1.49 + attendees.append((attendee, {"PARTSTAT" : "NEEDS-ACTION", "RSVP" : "TRUE"}))
1.50 +
1.51 + self.obj["ATTENDEE"] = attendees
1.52
1.53 self.update_dtstamp()
1.54 self.set_sequence(update)
1.55 @@ -551,10 +561,6 @@
1.56
1.57 is_organiser = get_uri(obj.get_value("ORGANIZER")) == self.user
1.58
1.59 - # Obtain any participants to be removed.
1.60 -
1.61 - removed = args.get("remove")
1.62 -
1.63 # Obtain the user's timezone and process datetime values.
1.64
1.65 update = False
1.66 @@ -597,6 +603,11 @@
1.67 if dtstart >= dtend:
1.68 return ["dtstart", "dtend"]
1.69
1.70 + # Obtain any participants to be added or removed.
1.71 +
1.72 + removed = args.get("remove")
1.73 + added = args.get("added")
1.74 +
1.75 # Process any action.
1.76
1.77 handled = True
1.78 @@ -609,7 +620,7 @@
1.79
1.80 if reply and handler.process_received_request(update) or \
1.81 is_organiser and (invite or cancel) and \
1.82 - handler.process_created_request(invite and "REQUEST" or "CANCEL", update, removed):
1.83 + handler.process_created_request(invite and "REQUEST" or "CANCEL", update, removed, added):
1.84
1.85 self.remove_request(uid)
1.86
1.87 @@ -764,6 +775,28 @@
1.88 # Provide controls to change the displayed object.
1.89
1.90 args = self.env.get_args()
1.91 +
1.92 + # Add or remove new attendees.
1.93 + # This does not affect the stored object.
1.94 +
1.95 + existing_attendees = uri_values(obj.get_values("ATTENDEE"))
1.96 + new_attendees = args.get("added", [])
1.97 + new_attendee = args.get("attendee", [""])[0]
1.98 +
1.99 + if args.has_key("add"):
1.100 + if new_attendee.strip():
1.101 + new_attendee = get_uri(new_attendee.strip())
1.102 + if new_attendee not in new_attendees and new_attendee not in existing_attendees:
1.103 + new_attendees.append(new_attendee)
1.104 + new_attendee = ""
1.105 +
1.106 + if args.has_key("removenew"):
1.107 + removed_attendee = args["removenew"][0]
1.108 + if removed_attendee in new_attendees:
1.109 + new_attendees.remove(removed_attendee)
1.110 +
1.111 + # Configure the start and end datetimes.
1.112 +
1.113 dtend_control = args.get("dtend-control", [None])[0]
1.114 dttimes_control = args.get("dttimes-control", [None])[0]
1.115 with_time = dttimes_control == "enable"
1.116 @@ -895,7 +928,12 @@
1.117 if not items:
1.118 continue
1.119
1.120 - page.th(label, class_="objectheading", rowspan=len(items))
1.121 + rowspan = len(items)
1.122 +
1.123 + if name == "ATTENDEE":
1.124 + rowspan += len(new_attendees) + 1
1.125 +
1.126 + page.th(label, class_="objectheading", rowspan=rowspan)
1.127
1.128 first = True
1.129
1.130 @@ -914,12 +952,15 @@
1.131
1.132 partstat = attr.get("PARTSTAT")
1.133 if value == self.user and (not is_organiser or name == "ORGANIZER"):
1.134 - self._show_menu("partstat", partstat, self.partstat_items)
1.135 + self._show_menu("partstat", partstat, self.partstat_items, "partstat")
1.136 else:
1.137 page.span(dict(self.partstat_items).get(partstat, ""), class_="partstat")
1.138
1.139 if is_organiser and name == "ATTENDEE":
1.140 - page.input(name="remove", type="checkbox", value=value, id="remove-%d" % i, class_="remove")
1.141 + if value in args.get("remove", []):
1.142 + page.input(name="remove", type="checkbox", value=value, id="remove-%d" % i, class_="remove", checked="checked")
1.143 + else:
1.144 + page.input(name="remove", type="checkbox", value=value, id="remove-%d" % i, class_="remove")
1.145 page.label("Remove", for_="remove-%d" % i, class_="remove")
1.146 page.label("Uninvited", for_="remove-%d" % i, class_="removed")
1.147
1.148 @@ -930,6 +971,25 @@
1.149 page.td.close()
1.150 page.tr.close()
1.151
1.152 + # Allow more attendees to be specified.
1.153 +
1.154 + if is_organiser and name == "ATTENDEE":
1.155 + for i, attendee in enumerate(new_attendees):
1.156 + page.tr()
1.157 + page.td()
1.158 + page.input(name="added", type="value", value=attendee)
1.159 + page.input(name="removenew", type="submit", value=attendee, id="removenew-%d" % i, class_="remove")
1.160 + page.label("Remove", for_="removenew-%d" % i, class_="remove")
1.161 + page.td.close()
1.162 + page.tr.close()
1.163 + page.tr()
1.164 + page.td()
1.165 + page.input(name="attendee", type="value", value=new_attendee)
1.166 + page.input(name="add", type="submit", value="add", id="add-%d" % i, class_="add")
1.167 + page.label("Add", for_="add-%d" % i, class_="add")
1.168 + page.td.close()
1.169 + page.tr.close()
1.170 +
1.171 page.tbody.close()
1.172 page.table.close()
1.173
1.174 @@ -1566,15 +1626,15 @@
1.175 identifier = "slot-%s" % value
1.176 return value, identifier
1.177
1.178 - def _show_menu(self, name, default, items):
1.179 + def _show_menu(self, name, default, items, class_=""):
1.180 page = self.page
1.181 values = self.env.get_args().get(name, [default])
1.182 page.select(name=name)
1.183 for v, label in items:
1.184 if v in values:
1.185 - page.option(label, value=v, selected="selected")
1.186 + page.option(label, value=v, selected="selected", class_=class_)
1.187 else:
1.188 - page.option(label, value=v)
1.189 + page.option(label, value=v, class_=class_)
1.190 page.select.close()
1.191
1.192 def _show_date_controls(self, name, default, attr, tzid):