imip-agent

Changeset

667:4d441e96f22f
2015-08-29 Paul Boddie raw files shortlog changelog graph Added a preference to define overall participation in the calendar system. Changed the test handler to work with non-store objects so that unstored events can be tested with the outgoing message handler. Improved the preferences documentation.
docs/preferences.txt (file) imiptools/__init__.py (file) imiptools/client.py (file) tests/templates/event-request-person-object.txt (file) tests/test_handle.py (file) tests/test_person_non_participation.sh (file)
     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"