# HG changeset patch # User Paul Boddie # Date 1443553383 -7200 # Node ID 481df9da00f0e1f030e9c6884d68c8b3de22d922 # Parent b3bf74310dd5365b997085aa051524b42187a045 Added support for address usage when specifying attendees, along with usage of the CN attribute for attendees and organisers. diff -r b3bf74310dd5 -r 481df9da00f0 imipweb/calendar.py --- a/imipweb/calendar.py Tue Sep 29 19:28:40 2015 +0200 +++ b/imipweb/calendar.py Tue Sep 29 21:03:03 2015 +0200 @@ -20,7 +20,7 @@ """ from datetime import datetime -from imiptools.data import get_address, get_uri, uri_values +from imiptools.data import get_address, get_uri, uri_parts from imiptools.dates import format_datetime, get_datetime, \ get_datetime_item, get_end_of_day, get_start_of_day, \ get_start_of_next_day, get_timestamp, ends_on_same_day, \ @@ -123,21 +123,29 @@ start, end = coalesced[0] start_value, start_attr = get_datetime_item(start, tzid) end_value, end_attr = get_datetime_item(end, tzid) + user_attr = self.get_user_attributes() rwrite(("UID", {}, uid)) rwrite(("SUMMARY", {}, summary or ("New event at %s" % utcnow))) rwrite(("DTSTAMP", {}, utcnow)) rwrite(("DTSTART", start_attr, start_value)) rwrite(("DTEND", end_attr, end_value)) - rwrite(("ORGANIZER", {}, self.user)) + rwrite(("ORGANIZER", user_attr, self.user)) + + cn_participants = uri_parts(filter(None, participants)) + participants = [] - participants = uri_values(filter(None, participants)) - - for participant in participants: - rwrite(("ATTENDEE", {"RSVP" : "TRUE", "PARTSTAT" : "NEEDS-ACTION"}, participant)) + for cn, participant in cn_participants: + d = {"RSVP" : "TRUE", "PARTSTAT" : "NEEDS-ACTION"} + if cn: + d["CN"] = cn + rwrite(("ATTENDEE", d, participant)) + participants.append(participant) if self.user not in participants: - rwrite(("ATTENDEE", {"PARTSTAT" : "ACCEPTED"}, self.user)) + d = {"PARTSTAT" : "ACCEPTED"} + d.update(user_attr) + rwrite(("ATTENDEE", d, self.user)) # Define additional occurrences if many slots are defined. diff -r b3bf74310dd5 -r 481df9da00f0 imipweb/event.py --- a/imipweb/event.py Tue Sep 29 19:28:40 2015 +0200 +++ b/imipweb/event.py Tue Sep 29 21:03:03 2015 +0200 @@ -19,7 +19,7 @@ this program. If not, see . """ -from imiptools.data import get_uri, uri_dict, uri_items, uri_values +from imiptools.data import get_uri, get_verbose_address, uri_dict, uri_items, uri_values from imiptools.dates import format_datetime, to_timezone from imiptools.mail import Messenger from imiptools.period import have_conflict @@ -101,7 +101,7 @@ return get_uri(self.obj.get_value("ORGANIZER")) == self.user def get_stored_attendees(self): - return uri_values(self.obj.get_values("ATTENDEE") or []) + return [get_verbose_address(value, attr) for value, attr in self.obj.get_items("ATTENDEE") or []] def get_stored_main_period(self): @@ -140,7 +140,7 @@ page = self.page args = self.env.get_args() - attendees = self.get_current_attendees() + attendees = uri_values(self.get_current_attendees()) is_attendee = self.user in attendees is_request = self._have_request(self.uid, self.recurrenceid) @@ -287,7 +287,7 @@ # Obtain details of attendees to supply attributes. - self.show_attendee(i, value, attendee_map.get(value)) + self.show_attendee(i, value, attendee_map.get(get_uri(value))) page.tr.close() # Allow more attendees to be specified. @@ -314,7 +314,10 @@ first = False page.td(class_="objectvalue %s" % field) - page.add(value) + if name == "ORGANIZER": + page.add(get_verbose_address(value, attr)) + else: + page.add(value) page.td.close() page.tr.close() @@ -338,13 +341,14 @@ page = self.page args = self.env.get_args() + attendee_uri = get_uri(attendee) partstat = attendee_attr and attendee_attr.get("PARTSTAT") page.td(class_="objectvalue") # Show a form control as organiser for new attendees. - if self.is_organiser() and self.can_edit_attendee(attendee): + if self.is_organiser() and self.can_edit_attendee(attendee_uri): self.control("attendee", "value", attendee, size="40") else: self.control("attendee", "hidden", attendee) @@ -353,14 +357,14 @@ # Show participation status, editable for the current user. - if attendee == self.user: + if attendee_uri == self.user: self.menu("partstat", partstat, self.partstat_items, "partstat") # Allow the participation indicator to act as a submit # button in order to refresh the page and show a control for # the current user, if indicated. - elif self.is_organiser() and self.attendee_is_new(attendee): + elif self.is_organiser() and self.attendee_is_new(attendee_uri): self.control("partstat-refresh", "submit", "refresh", id="partstat-%d" % i, class_="refresh") page.label(dict(self.partstat_items).get(partstat, ""), for_="partstat-%s" % i, class_="partstat") @@ -375,7 +379,7 @@ # Permit the removal of newly-added attendees. - remove_type = self.can_remove_attendee(attendee) and "submit" or "checkbox" + remove_type = self.can_remove_attendee(attendee_uri) and "submit" or "checkbox" self.control("remove", remove_type, str(i), str(i) in args.get("remove", []), id="remove-%d" % i, class_="remove") page.label("Remove", for_="remove-%d" % i, class_="remove") @@ -751,7 +755,7 @@ # Obtain any participants and those to be removed. - attendees = self.get_attendees_from_page() + attendees = map(lambda s: s and get_uri(s), self.get_attendees_from_page()) removed = [attendees[int(i)] for i in args.get("remove", [])] to_cancel = self.update_attendees(self.obj, attendees, removed) single_user = not attendees or attendees == [self.user] @@ -921,19 +925,9 @@ def get_attendees_from_page(self): - """ - Return attendees from the request, normalised for iCalendar purposes. - """ - - args = self.env.get_args() - attendees = [] + "Return attendees from the request." - for attendee in args.get("attendee", []): - if attendee.strip(): - attendee = get_uri(attendee) - attendees.append(attendee) - - return attendees + return self.env.get_args().get("attendee", []) def update_attendees_from_page(self):