1.1 --- a/docs/preferences.txt Sun Sep 13 02:52:21 2015 +0200
1.2 +++ b/docs/preferences.txt Sun Sep 13 02:58:48 2015 +0200
1.3 @@ -17,6 +17,21 @@
1.4
1.5 The default time zone/regime for calendars, new events and local times.
1.6
1.7 +add_method_response
1.8 +-------------------
1.9 +
1.10 +Default: refresh
1.11 +Alternatives (see below)
1.12 +
1.13 +Indicate how ADD methods shall be responded to when received by a recipient:
1.14 +
1.15 + add apply them to events as received
1.16 +
1.17 + ignore ignore attempts to add event occurrences
1.18 +
1.19 + refresh respond with a REFRESH message to obtain a proper
1.20 + request will all event details
1.21 +
1.22 event_refreshing
1.23 ----------------
1.24
2.1 --- a/imiptools/client.py Sun Sep 13 02:52:21 2015 +0200
2.2 +++ b/imiptools/client.py Sun Sep 13 02:58:48 2015 +0200
2.3 @@ -108,9 +108,16 @@
2.4 prefs = self.get_preferences()
2.5 return prefs and prefs.get("event_refreshing") == "always" or False
2.6
2.7 - def allow_organiser_replacement(self):
2.8 + def allow_add(self):
2.9 + return self.get_add_method_response() in ("add", "refresh")
2.10 +
2.11 + def get_add_method_response(self):
2.12 prefs = self.get_preferences()
2.13 - return prefs and prefs.get("organiser_replacement", "attendee") or False
2.14 + return prefs and prefs.get("add_method_response", "refresh") or "refresh"
2.15 +
2.16 + def get_organiser_replacement(self):
2.17 + prefs = self.get_preferences()
2.18 + return prefs and prefs.get("organiser_replacement", "attendee") or "attendee"
2.19
2.20 def have_manager(self):
2.21 return MANAGER_INTERFACE
3.1 --- a/imiptools/data.py Sun Sep 13 02:52:21 2015 +0200
3.2 +++ b/imiptools/data.py Sun Sep 13 02:58:48 2015 +0200
3.3 @@ -157,6 +157,9 @@
3.4 def get(self, name):
3.5 return self.details.get(name)
3.6
3.7 + def keys(self):
3.8 + return self.details.keys()
3.9 +
3.10 def __getitem__(self, name):
3.11 return self.details[name]
3.12
3.13 @@ -176,6 +179,11 @@
3.14 for name in names:
3.15 self.remove(name)
3.16
3.17 + def preserve(self, names):
3.18 + for name in self.keys():
3.19 + if not name in names:
3.20 + self.remove(name)
3.21 +
3.22 # Computed results.
3.23
3.24 def get_main_period_items(self, tzid):
4.1 --- a/imiptools/handlers/__init__.py Sun Sep 13 02:52:21 2015 +0200
4.2 +++ b/imiptools/handlers/__init__.py Sun Sep 13 02:58:48 2015 +0200
4.3 @@ -158,7 +158,7 @@
4.4 # Test against any previously-received organiser details.
4.5
4.6 if not self.is_recognised_organiser(organiser):
4.7 - replacement = self.allow_organiser_replacement()
4.8 + replacement = self.get_organiser_replacement()
4.9
4.10 # Allow any organiser as a replacement where indicated.
4.11
5.1 --- a/imiptools/handlers/person.py Sun Sep 13 02:52:21 2015 +0200
5.2 +++ b/imiptools/handlers/person.py Sun Sep 13 02:58:48 2015 +0200
5.3 @@ -30,7 +30,10 @@
5.4
5.5 def _add(self, queue=True):
5.6
5.7 - "Add a recurrence for the current object."
5.8 + """
5.9 + Add an event occurrence for the current object or produce a response
5.10 + that requests the event details to be sent again.
5.11 + """
5.12
5.13 # Obtain valid organiser and attendee details.
5.14
5.15 @@ -40,29 +43,49 @@
5.16
5.17 (organiser, organiser_attr), attendees = oa
5.18
5.19 - # Ignore unknown objects.
5.20 - # NOTE: We could issue a REFRESH to get such objects.
5.21 + # Request details where configured, doing so for unknown objects anyway.
5.22 +
5.23 + refreshing = not self.get_stored_object_version() or self.get_add_method_response() == "refresh"
5.24 +
5.25 + if refreshing:
5.26 +
5.27 + # Add SENT-BY details to the recipient's attributes.
5.28
5.29 - if not self.get_stored_object_version():
5.30 - return
5.31 + attendee_attr = attendees[self.user]
5.32 + self.update_sender(attendee_attr)
5.33 +
5.34 + # Make a new object with a minimal property selection.
5.35 +
5.36 + obj = self.obj.copy()
5.37 + obj.preserve(("ORGANIZER", "DTSTAMP", "UID", "RECURRENCE-ID"))
5.38 + obj["ATTENDEE"] = [(self.user, attendee_attr)]
5.39 +
5.40 + # Send a REFRESH message in response.
5.41 +
5.42 + self.add_result("REFRESH", [get_address(organiser)], obj.to_part("REFRESH"))
5.43
5.44 # Record the event as a recurrence of the parent object.
5.45
5.46 self.update_recurrenceid()
5.47
5.48 + # Update the recipient's record of the organiser's schedule.
5.49 +
5.50 + self.update_freebusy_from_organiser(organiser)
5.51 +
5.52 + # Stop if requesting the full event.
5.53 +
5.54 + if refreshing:
5.55 + return
5.56 +
5.57 + # Set the additional occurrence.
5.58 +
5.59 + self.store.set_event(self.user, self.uid, self.recurrenceid, self.obj.to_node())
5.60 +
5.61 # Queue any request, if appropriate.
5.62
5.63 if queue:
5.64 self.store.queue_request(self.user, self.uid, self.recurrenceid)
5.65
5.66 - # Update the recipient's record of the organiser's schedule.
5.67 -
5.68 - self.update_freebusy_from_organiser(organiser)
5.69 -
5.70 - # Set the additional occurrence.
5.71 -
5.72 - self.store.set_event(self.user, self.uid, self.recurrenceid, self.obj.to_node())
5.73 -
5.74 return True
5.75
5.76 def _record(self, from_organiser=True, queue=False, cancel=False):
5.77 @@ -205,7 +228,7 @@
5.78
5.79 "Queue a suggested additional recurrence for any active event."
5.80
5.81 - if self._add(queue=True):
5.82 + if self.allow_add() and self._add(queue=True):
5.83 return self.wrap("An addition to an event has been received.")
5.84
5.85 def cancel(self):
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tests/templates/event-request-person-recurring-add.txt Sun Sep 13 02:58:48 2015 +0200
6.3 @@ -0,0 +1,35 @@
6.4 +Content-Type: multipart/alternative; boundary="===============0047278175=="
6.5 +MIME-Version: 1.0
6.6 +From: paul.boddie@example.com
6.7 +To: vincent.vole@example.com
6.8 +Subject: Invitation!
6.9 +
6.10 +--===============0047278175==
6.11 +Content-Type: text/plain; charset="us-ascii"
6.12 +MIME-Version: 1.0
6.13 +Content-Transfer-Encoding: 7bit
6.14 +
6.15 +This message contains an event.
6.16 +
6.17 +--===============0047278175==
6.18 +MIME-Version: 1.0
6.19 +Content-Transfer-Encoding: 7bit
6.20 +Content-Type: text/calendar; charset="us-ascii"; method="ADD"
6.21 +
6.22 +BEGIN:VCALENDAR
6.23 +PRODID:-//imip-agent/test//EN
6.24 +METHOD:ADD
6.25 +VERSION:2.0
6.26 +BEGIN:VEVENT
6.27 +ORGANIZER:mailto:paul.boddie@example.com
6.28 +ATTENDEE;RSVP=TRUE:mailto:vincent.vole@example.com
6.29 +ATTENDEE;RSVP=TRUE:mailto:paul.boddie@example.com
6.30 +DTSTAMP:20141009T182400Z
6.31 +DTSTART;TZID=Europe/Oslo:20150109T100000
6.32 +DTEND;TZID=Europe/Oslo:20150109T110000
6.33 +SUMMARY:Another event occurrence
6.34 +UID:event8@example.com
6.35 +END:VEVENT
6.36 +END:VCALENDAR
6.37 +
6.38 +--===============0047278175==--
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/tests/test_person_invitation_add.sh Sun Sep 13 02:58:48 2015 +0200
7.3 @@ -0,0 +1,178 @@
7.4 +#!/bin/sh
7.5 +
7.6 +THIS_DIR=`dirname $0`
7.7 +
7.8 +TEMPLATES="$THIS_DIR/templates"
7.9 +PERSON_SCRIPT="$THIS_DIR/../imip_person.py"
7.10 +SHOWMAIL="$THIS_DIR/../tools/showmail.py"
7.11 +STORE=/tmp/store
7.12 +STATIC=/tmp/static
7.13 +PREFS=/tmp/prefs
7.14 +ARGS="-S $STORE -P $STATIC -p $PREFS -d"
7.15 +USER="mailto:vincent.vole@example.com"
7.16 +SENDER="mailto:paul.boddie@example.com"
7.17 +FBFILE="$STORE/$USER/freebusy"
7.18 +FBOTHERFILE="$STORE/$USER/freebusy-other/$SENDER"
7.19 +FBSENDERFILE="$STORE/$SENDER/freebusy"
7.20 +FBSENDEROTHERFILE="$STORE/$SENDER/freebusy-other/$USER"
7.21 +TAB=`printf '\t'`
7.22 +
7.23 +OUTGOING_SCRIPT="$THIS_DIR/../imip_person_outgoing.py"
7.24 +
7.25 +PYTHONPATH="$THIS_DIR/.."
7.26 +export PYTHONPATH
7.27 +
7.28 +ACCEPT_SCRIPT="$THIS_DIR/test_handle.py"
7.29 +ACCEPT_ARGS="accept $STORE"
7.30 +
7.31 +DECLINE_SCRIPT="$THIS_DIR/test_handle.py"
7.32 +DECLINE_ARGS="decline $STORE"
7.33 +
7.34 +ERROR=err.tmp
7.35 +
7.36 +rm -r $STORE
7.37 +rm -r $STATIC
7.38 +rm -r $PREFS
7.39 +rm $ERROR
7.40 +rm out*.tmp
7.41 +
7.42 +mkdir -p "$PREFS/$USER"
7.43 +echo 'Europe/Oslo' > "$PREFS/$USER/TZID"
7.44 +echo 'share' > "$PREFS/$USER/freebusy_sharing"
7.45 +
7.46 +mkdir -p "$PREFS/$SENDER"
7.47 +echo 'Europe/Oslo' > "$PREFS/$USER/TZID"
7.48 +echo 'always' > "$PREFS/$SENDER/event_refreshing"
7.49 +
7.50 +# Test event request registration in the outgoing handler.
7.51 +
7.52 +"$OUTGOING_SCRIPT" $ARGS < "$TEMPLATES/event-request-person-recurring.txt" 2>> $ERROR
7.53 +
7.54 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBSENDERFILE" \
7.55 +&& echo "Success" \
7.56 +|| echo "Failed"
7.57 +
7.58 +# Present the request to the recipient.
7.59 +
7.60 + "$PERSON_SCRIPT" $ARGS < "$TEMPLATES/event-request-person-recurring.txt" 2>> $ERROR \
7.61 +| "$SHOWMAIL" \
7.62 +> out2.tmp
7.63 +
7.64 + ! grep -q 'METHOD:REPLY' out2.tmp \
7.65 +&& echo "Success" \
7.66 +|| echo "Failed"
7.67 +
7.68 + ! [ -e "$FBFILE" ] \
7.69 +|| ! grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBFILE" \
7.70 +&& echo "Success" \
7.71 +|| echo "Failed"
7.72 +
7.73 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBOTHERFILE" \
7.74 +&& echo "Success" \
7.75 +|| echo "Failed"
7.76 +
7.77 +# Test acceptance and registration in the outgoing handler.
7.78 +
7.79 + "$ACCEPT_SCRIPT" $ACCEPT_ARGS "$USER" "event8@example.com" 2>> $ERROR \
7.80 +| tee out3.tmp \
7.81 +| "$OUTGOING_SCRIPT" $ARGS 2>> $ERROR
7.82 +
7.83 + "$SHOWMAIL" < out3.tmp | grep -q 'METHOD:REPLY' \
7.84 +&& echo "Success" \
7.85 +|| echo "Failed"
7.86 +
7.87 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBFILE" \
7.88 +&& echo "Success" \
7.89 +|| echo "Failed"
7.90 +
7.91 +# Present the result to the recipient.
7.92 +
7.93 + "$PERSON_SCRIPT" $ARGS < out3.tmp 2>> $ERROR \
7.94 +| "$SHOWMAIL" \
7.95 +> out4.tmp
7.96 +
7.97 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBSENDEROTHERFILE" \
7.98 +&& echo "Success" \
7.99 +|| echo "Failed"
7.100 +
7.101 +# Attempt to add an occurrence to the event.
7.102 +
7.103 +"$OUTGOING_SCRIPT" $ARGS < "$TEMPLATES/event-request-person-recurring-add.txt" 2>> $ERROR
7.104 +
7.105 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBSENDERFILE" \
7.106 +&& grep -q "^20150109T090000Z${TAB}20150109T100000Z" "$FBSENDERFILE" \
7.107 +&& echo "Success" \
7.108 +|| echo "Failed"
7.109 +
7.110 +# Present the request to the recipient.
7.111 +
7.112 + "$PERSON_SCRIPT" $ARGS < "$TEMPLATES/event-request-person-recurring-add.txt" 2>> $ERROR \
7.113 +| "$SHOWMAIL" \
7.114 +> out5.tmp
7.115 +
7.116 + grep -q 'METHOD:REFRESH' out5.tmp \
7.117 +&& echo "Success" \
7.118 +|| echo "Failed"
7.119 +
7.120 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBFILE" \
7.121 +&& ! grep -q "^20150109T090000Z${TAB}20150109T100000Z" "$FBFILE" \
7.122 +&& echo "Success" \
7.123 +|| echo "Failed"
7.124 +
7.125 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBOTHERFILE" \
7.126 +&& grep -q "^20150109T090000Z${TAB}20150109T100000Z" "$FBOTHERFILE" \
7.127 +&& echo "Success" \
7.128 +|| echo "Failed"
7.129 +
7.130 +# Present the refresh message to the organiser.
7.131 +
7.132 + "$PERSON_SCRIPT" $ARGS < out5.tmp 2>> $ERROR \
7.133 +| "$SHOWMAIL" \
7.134 +> out6.tmp
7.135 +
7.136 + grep -q 'METHOD:REQUEST' out6.tmp \
7.137 +&& echo "Success" \
7.138 +|| echo "Failed"
7.139 +
7.140 +# Present the request to the recipient.
7.141 +
7.142 + "$PERSON_SCRIPT" $ARGS < out6.tmp 2>> $ERROR \
7.143 +| "$SHOWMAIL" \
7.144 +> out7.tmp
7.145 +
7.146 + ! grep -q 'METHOD:REPLY' out7.tmp \
7.147 +&& echo "Success" \
7.148 +|| echo "Failed"
7.149 +
7.150 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBFILE" \
7.151 +&& ! grep -q "^20150109T090000Z${TAB}20150109T100000Z" "$FBFILE" \
7.152 +&& echo "Success" \
7.153 +|| echo "Failed"
7.154 +
7.155 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBOTHERFILE" \
7.156 +&& grep -q "^20150109T090000Z${TAB}20150109T100000Z" "$FBOTHERFILE" \
7.157 +&& echo "Success" \
7.158 +|| echo "Failed"
7.159 +
7.160 +# Test acceptance and registration in the outgoing handler.
7.161 +
7.162 + "$ACCEPT_SCRIPT" $ACCEPT_ARGS "$USER" "event8@example.com" 2>> $ERROR \
7.163 +| tee out8.tmp \
7.164 +| "$OUTGOING_SCRIPT" $ARGS 2>> $ERROR
7.165 +
7.166 + "$SHOWMAIL" < out8.tmp | grep -q 'METHOD:REPLY' \
7.167 +&& echo "Success" \
7.168 +|| echo "Failed"
7.169 +
7.170 + "$ACCEPT_SCRIPT" $ACCEPT_ARGS "$USER" "event8@example.com" "20150109T090000Z" 2>> $ERROR \
7.171 +| tee out9.tmp \
7.172 +| "$OUTGOING_SCRIPT" $ARGS 2>> $ERROR
7.173 +
7.174 + "$SHOWMAIL" < out9.tmp | grep -q 'METHOD:REPLY' \
7.175 +&& echo "Success" \
7.176 +|| echo "Failed"
7.177 +
7.178 + grep -q "^20141212T090000Z${TAB}20141212T100000Z" "$FBFILE" \
7.179 +&& grep -q "^20150109T090000Z${TAB}20150109T100000Z" "$FBFILE" \
7.180 +&& echo "Success" \
7.181 +|| echo "Failed"