1.1 --- a/imiptools/client.py Sun Sep 13 18:23:42 2015 +0200
1.2 +++ b/imiptools/client.py Sun Sep 13 19:00:15 2015 +0200
1.3 @@ -19,7 +19,7 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -from datetime import datetime
1.8 +from datetime import datetime, timedelta
1.9 from imiptools.config import MANAGER_INTERFACE
1.10 from imiptools.data import Object, get_address, get_uri, get_window_end, \
1.11 is_new_object, make_freebusy, to_part, \
1.12 @@ -115,6 +115,31 @@
1.13 prefs = self.get_preferences()
1.14 return prefs and prefs.get("add_method_response", "refresh") or "refresh"
1.15
1.16 + def get_offer_period(self):
1.17 +
1.18 + """
1.19 + Decode a specification of one of the following forms...
1.20 +
1.21 + <number of seconds>
1.22 + <number of days>d
1.23 + """
1.24 +
1.25 + prefs = self.get_preferences()
1.26 + duration = prefs and prefs.get("freebusy_offers")
1.27 + if duration:
1.28 + try:
1.29 + if duration.endswith("d"):
1.30 + return timedelta(days=int(duration[:-1]))
1.31 + else:
1.32 + return timedelta(seconds=int(duration))
1.33 +
1.34 + # NOTE: Should probably report an error somehow.
1.35 +
1.36 + except ValueError:
1.37 + return None
1.38 + else:
1.39 + return None
1.40 +
1.41 def get_organiser_replacement(self):
1.42 prefs = self.get_preferences()
1.43 return prefs and prefs.get("organiser_replacement", "attendee") or "attendee"
1.44 @@ -268,16 +293,19 @@
1.45
1.46 return None
1.47
1.48 - def update_freebusy(self, freebusy, periods, transp, uid, recurrenceid, summary, organiser):
1.49 + def update_freebusy(self, freebusy, periods, transp, uid, recurrenceid, summary, organiser, expires=None):
1.50
1.51 """
1.52 Update the 'freebusy' collection with the given 'periods', indicating a
1.53 'transp' status, explicit 'uid' and 'recurrenceid' to indicate either a
1.54 recurrence or the parent event. The 'summary' and 'organiser' must also
1.55 be provided.
1.56 +
1.57 + An optional 'expires' datetime string can be provided to tag a free/busy
1.58 + offer.
1.59 """
1.60
1.61 - update_freebusy(freebusy, periods, transp, uid, recurrenceid, summary, organiser)
1.62 + update_freebusy(freebusy, periods, transp, uid, recurrenceid, summary, organiser, expires)
1.63
1.64 class ClientForObject(Client):
1.65
1.66 @@ -590,7 +618,7 @@
1.67 recurrenceid = self.get_recurrence_start_point(recurrenceid)
1.68 remove_affected_period(freebusy, self.uid, recurrenceid)
1.69
1.70 - def update_freebusy(self, freebusy, user, as_organiser):
1.71 + def update_freebusy(self, freebusy, user, as_organiser, offer=False):
1.72
1.73 """
1.74 Update the 'freebusy' collection for this event with the periods and
1.75 @@ -598,6 +626,9 @@
1.76 identity and the attendance details provided for them, indicating
1.77 whether the update is being done 'as_organiser' (for the organiser of
1.78 an event) or not.
1.79 +
1.80 + If 'offer' is set to a true value, any free/busy updates will be tagged
1.81 + with an expiry time.
1.82 """
1.83
1.84 # Obtain the stored object if the current object is not issued by the
1.85 @@ -619,21 +650,37 @@
1.86 obj.get_value("TRANSP") or \
1.87 "OPAQUE"
1.88
1.89 + # Calculate any expiry time. If no offer period is defined, do not
1.90 + # record the offer periods.
1.91 +
1.92 + if offer:
1.93 + offer_period = self.get_offer_period()
1.94 + if offer_period:
1.95 + expires = format_datetime(to_timezone(datetime.utcnow(), "UTC") + offer_period)
1.96 + else:
1.97 + return
1.98 + else:
1.99 + expires = None
1.100 +
1.101 # Perform the low-level update.
1.102
1.103 Client.update_freebusy(self, freebusy, periods, transp,
1.104 self.uid, self.recurrenceid,
1.105 obj.get_value("SUMMARY"),
1.106 - obj.get_value("ORGANIZER"))
1.107 + obj.get_value("ORGANIZER"),
1.108 + expires)
1.109
1.110 def update_freebusy_for_participant(self, freebusy, user, for_organiser=False,
1.111 - updating_other=False):
1.112 + updating_other=False, offer=False):
1.113
1.114 """
1.115 Update the 'freebusy' collection for the given 'user', indicating
1.116 whether the update is 'for_organiser' (being done for the organiser of
1.117 an event) or not, and whether it is 'updating_other' (meaning another
1.118 user's details).
1.119 +
1.120 + If 'offer' is set to a true value, any free/busy updates will be tagged
1.121 + with an expiry time.
1.122 """
1.123
1.124 # Record in the free/busy details unless a non-participating attendee.
1.125 @@ -642,7 +689,8 @@
1.126 if self.is_participating(user, for_organiser and not updating_other):
1.127 self.update_freebusy(freebusy, user,
1.128 for_organiser and not updating_other or
1.129 - not for_organiser and updating_other
1.130 + not for_organiser and updating_other,
1.131 + offer
1.132 )
1.133 else:
1.134 self.remove_from_freebusy(freebusy)