1.1 --- a/docs/preferences.txt Fri Aug 21 14:47:53 2015 +0200
1.2 +++ b/docs/preferences.txt Sat Aug 29 00:14:32 2015 +0200
1.3 @@ -1,19 +1,74 @@
1.4 -General user preferences are as follows:
1.5 +Preferences and Settings
1.6 +========================
1.7 +
1.8 +LANG
1.9 +----
1.10
1.11 -LANG (en) language for messages and interfaces
1.12 +Default: en (English)
1.13 +Alternatives: (any recognised and supported locale)
1.14 +
1.15 +The language for messages and user interface text.
1.16 +
1.17 +TZID
1.18 +----
1.19 +
1.20 +Default: system timezone (see /etc/timezone)
1.21 +Alternatives: (any recognised Olson time zone identifier)
1.22
1.23 -The user preferences for message and calendar functionality are as follows:
1.24 +The default time zone/regime for calendars, new events and local times.
1.25 +
1.26 +freebusy_bundling
1.27 +-----------------
1.28 +
1.29 +Default: never
1.30 +Alternative: always
1.31
1.32 -freebusy_bundling always bundle free/busy details with other
1.33 - payloads
1.34 +Indicate whether to bundle free/busy details with other payloads such as
1.35 +event and free/busy objects.
1.36 +
1.37 +freebusy_messages
1.38 +-----------------
1.39 +
1.40 +Default: none
1.41 +Alternative: notify
1.42 +
1.43 +Indicate whether recipients are notified about received free/busy payloads.
1.44
1.45 -freebusy_messages notify notify recipients of received free/busy
1.46 - payloads
1.47 +freebusy_sharing
1.48 +----------------
1.49 +
1.50 +Default: no
1.51 +Alternative: share
1.52 +
1.53 +Share free/busy details generally:
1.54 +
1.55 + * bundling in e-mail messages if bundling is configured
1.56 + * responding to free/busy requests via e-mail
1.57 + * publishing as Web resources if a static Web resource is configured
1.58 +
1.59 +incoming
1.60 +--------
1.61 +
1.62 +Default: summary-wraps-message
1.63 +Alternatives: (see below)
1.64
1.65 -freebusy_sharing share share free/busy details generally:
1.66 - * bundling in e-mail messages if bundling
1.67 - is configured
1.68 - * responding to free/busy requests via
1.69 - e-mail
1.70 - * publishing as Web resources if a static
1.71 - Web resource is configured
1.72 +Define how incoming event messages are delivered to recipients:
1.73 +
1.74 + * message-only (deliver only the incoming message as it was received)
1.75 + * message-then-summary (deliver the message first followed by a summary
1.76 + message)
1.77 + * summary-then-message (deliver a summary first followed by the message)
1.78 + * summary-only (deliver only a summary of the message)
1.79 +
1.80 +participating
1.81 +-------------
1.82 +
1.83 +Default: participate
1.84 +Alternative: no
1.85 +
1.86 +Indicate whether a recipient participates in the calendar system. Note that
1.87 +participation by default occurs because the handler programs will be defined
1.88 +in the mail system for recipients fulfilling certain criteria; other
1.89 +recipients will be handled in other ways. Thus, initial non-participation must
1.90 +be defined by initialising this setting to "no" for all eligible users, if
1.91 +this is the general policy on initial calendar system participation.
2.1 --- a/imiptools/__init__.py Fri Aug 21 14:47:53 2015 +0200
2.2 +++ b/imiptools/__init__.py Sat Aug 29 00:14:32 2015 +0200
2.3 @@ -233,18 +233,23 @@
2.4 for name, cls in self.handlers])
2.5 handled = False
2.6
2.7 - # Check for returned messages.
2.8 + # Check for participating recipients. Non-participating recipients will
2.9 + # have their messages left as being unhandled.
2.10 +
2.11 + if self.is_participating():
2.12 +
2.13 + # Check for returned messages.
2.14
2.15 - for part in msg.walk():
2.16 - if part.get_content_type() == "message/delivery-status":
2.17 - break
2.18 - else:
2.19 for part in msg.walk():
2.20 - if part.get_content_type() in itip_content_types and \
2.21 - part.get_param("method"):
2.22 + if part.get_content_type() == "message/delivery-status":
2.23 + break
2.24 + else:
2.25 + for part in msg.walk():
2.26 + if part.get_content_type() in itip_content_types and \
2.27 + part.get_param("method"):
2.28
2.29 - handle_itip_part(part, handlers)
2.30 - handled = True
2.31 + handle_itip_part(part, handlers)
2.32 + handled = True
2.33
2.34 # When processing outgoing messages, no replies or deliveries are
2.35 # performed.
2.36 @@ -302,7 +307,6 @@
2.37 # Determine whether to wrap, accompany or replace the message.
2.38
2.39 prefs = self.get_preferences()
2.40 -
2.41 incoming = prefs.get("incoming")
2.42
2.43 if incoming == "message-only":
3.1 --- a/imiptools/client.py Fri Aug 21 14:47:53 2015 +0200
3.2 +++ b/imiptools/client.py Sat Aug 29 00:14:32 2015 +0200
3.3 @@ -69,6 +69,10 @@
3.4 def get_window_end(self):
3.5 return get_window_end(self.get_tzid(), self.get_window_size())
3.6
3.7 + def is_participating(self):
3.8 + prefs = self.get_preferences()
3.9 + return prefs and prefs.get("participating", "participate") != "no" or False
3.10 +
3.11 def is_sharing(self):
3.12 prefs = self.get_preferences()
3.13 return prefs and prefs.get("freebusy_sharing") == "share" or False
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/tests/templates/event-request-person-object.txt Sat Aug 29 00:14:32 2015 +0200
4.3 @@ -0,0 +1,10 @@
4.4 +BEGIN:VEVENT
4.5 +ORGANIZER:mailto:paul.boddie@example.com
4.6 +ATTENDEE;ROLE=CHAIR:mailto:paul.boddie@example.com
4.7 +ATTENDEE;RSVP=TRUE:mailto:vincent.vole@example.com
4.8 +DTSTAMP:20141125T004600Z
4.9 +DTSTART;TZID=Europe/Oslo:20141126T160000
4.10 +DTEND;TZID=Europe/Oslo:20141126T170000
4.11 +SUMMARY:Meeting at 4pm
4.12 +UID:event6@example.com
4.13 +END:VEVENT
5.1 --- a/tests/test_handle.py Fri Aug 21 14:47:53 2015 +0200
5.2 +++ b/tests/test_handle.py Sat Aug 29 00:14:32 2015 +0200
5.3 @@ -20,7 +20,7 @@
5.4 """
5.5
5.6 from imiptools.client import ClientForObject
5.7 -from imiptools.data import Object, get_address
5.8 +from imiptools.data import Object, get_address, parse_object
5.9 from imiptools.mail import Messenger
5.10 import imip_store
5.11 import sys
5.12 @@ -69,26 +69,34 @@
5.13
5.14 if __name__ == "__main__":
5.15 try:
5.16 - nargs = 5
5.17 - accept, store_dir, user, uid, recurrenceid = (sys.argv[1:nargs+1] + [None])[:nargs]
5.18 + minargs = 3; maxargs = 5
5.19 + accept, store_dir, user, uid, recurrenceid = (sys.argv[1:maxargs+1] + ([None] * (maxargs - minargs)))[:maxargs]
5.20 except ValueError:
5.21 print >>sys.stderr, "Need 'accept' or 'decline', a store directory, user URI, event UID and optional RECURRENCE-ID."
5.22 print >>sys.stderr, "The RECURRENCE-ID must be in the form employed by the store."
5.23 + print >>sys.stderr
5.24 + print >>sys.stderr, "Alternatively, omit the UID and RECURRENCE-ID and provide event-only details on standard input"
5.25 + print >>sys.stderr, "to force the script to handle an event not already present in the store."
5.26 sys.exit(1)
5.27
5.28 store = imip_store.FileStore(store_dir)
5.29 - fragment = store.get_event(user, uid, recurrenceid)
5.30 +
5.31 + if uid is not None:
5.32 + fragment = store.get_event(user, uid, recurrenceid)
5.33
5.34 - if not fragment:
5.35 - print >>sys.stderr, "No such event:", uid, recurrenceid
5.36 - sys.exit(1)
5.37 + if not fragment:
5.38 + print >>sys.stderr, "No such event:", uid, recurrenceid
5.39 + sys.exit(1)
5.40 + else:
5.41 + fragment = parse_object(sys.stdin, "utf-8")
5.42
5.43 obj = Object(fragment)
5.44 - handler = TestClient(obj, user, Messenger())
5.45 + handler = TestClient(obj, user, Messenger(), store)
5.46 response = handler.handle_request(accept == "accept")
5.47
5.48 if response:
5.49 - store.dequeue_request(user, uid, recurrenceid)
5.50 + if uid is not None:
5.51 + store.dequeue_request(user, uid, recurrenceid)
5.52 print response
5.53 else:
5.54 sys.exit(1)
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/tests/test_person_non_participation.sh Sat Aug 29 00:14:32 2015 +0200
6.3 @@ -0,0 +1,71 @@
6.4 +#!/bin/sh
6.5 +
6.6 +THIS_DIR=`dirname $0`
6.7 +
6.8 +TEMPLATES="$THIS_DIR/templates"
6.9 +PERSON_SCRIPT="$THIS_DIR/../imip_person.py"
6.10 +SHOWMAIL="$THIS_DIR/../tools/showmail.py"
6.11 +STORE=/tmp/store
6.12 +STATIC=/tmp/static
6.13 +PREFS=/tmp/prefs
6.14 +ARGS="-S $STORE -P $STATIC -p $PREFS -d"
6.15 +USER="mailto:vincent.vole@example.com"
6.16 +SENDER="mailto:paul.boddie@example.com"
6.17 +FBFILE="$STORE/$USER/freebusy"
6.18 +FBOTHERFILE="$STORE/$USER/freebusy-other/$SENDER"
6.19 +TAB=`printf '\t'`
6.20 +
6.21 +OUTGOING_SCRIPT="$THIS_DIR/../imip_person_outgoing.py"
6.22 +
6.23 +PYTHONPATH="$THIS_DIR/.."
6.24 +export PYTHONPATH
6.25 +
6.26 +ACCEPT_SCRIPT="$THIS_DIR/test_handle.py"
6.27 +ACCEPT_ARGS="accept $STORE"
6.28 +
6.29 +DECLINE_SCRIPT="$THIS_DIR/test_handle.py"
6.30 +DECLINE_ARGS="decline $STORE"
6.31 +
6.32 +ERROR=err.tmp
6.33 +
6.34 +rm -r $STORE
6.35 +rm -r $STATIC
6.36 +rm -r $PREFS
6.37 +rm $ERROR
6.38 +rm out*.tmp
6.39 +
6.40 +mkdir -p "$PREFS/$USER"
6.41 +echo 'no' > "$PREFS/$USER/participating"
6.42 +
6.43 + "$PERSON_SCRIPT" $ARGS < "$TEMPLATES/fb-request-person-all.txt" 2>> $ERROR \
6.44 +| "$SHOWMAIL" \
6.45 +> out0.tmp
6.46 +
6.47 + ! grep -q 'METHOD:REPLY' out0.tmp \
6.48 +&& echo "Success" \
6.49 +|| echo "Failed"
6.50 +
6.51 + "$PERSON_SCRIPT" $ARGS < "$TEMPLATES/event-request-person.txt" 2>> $ERROR \
6.52 +| "$SHOWMAIL" \
6.53 +> out2.tmp
6.54 +
6.55 + ! grep -q 'METHOD:REPLY' out2.tmp \
6.56 +&& echo "Success" \
6.57 +|| echo "Failed"
6.58 +
6.59 + ! [ -e "$FBFILE" ] \
6.60 +&& echo "Success" \
6.61 +|| echo "Failed"
6.62 +
6.63 + ! [ -e "$FBOTHERFILE" ] \
6.64 +&& echo "Success" \
6.65 +|| echo "Failed"
6.66 +
6.67 + "$ACCEPT_SCRIPT" $ACCEPT_ARGS "$USER" < "$TEMPLATES/event-request-person-object.txt" \
6.68 +| tee out3.tmp \
6.69 +| "$OUTGOING_SCRIPT" $ARGS
6.70 +
6.71 + ! [ -e "$FBFILE" ] \
6.72 +|| ! grep -q "^20141126T150000Z${TAB}20141126T160000Z" "$FBFILE" \
6.73 +&& echo "Success" \
6.74 +|| echo "Failed"