1.1 --- a/docs/preferences.txt Mon Aug 31 15:44:46 2015 +0200
1.2 +++ b/docs/preferences.txt Mon Aug 31 18:09:31 2015 +0200
1.3 @@ -54,11 +54,14 @@
1.4
1.5 Define how incoming event messages are delivered to recipients:
1.6
1.7 - * message-only (deliver only the incoming message as it was received)
1.8 - * message-then-summary (deliver the message first followed by a summary
1.9 - message)
1.10 - * summary-then-message (deliver a summary first followed by the message)
1.11 - * summary-only (deliver only a summary of the message)
1.12 + message-only deliver only the incoming message as it was received
1.13 +
1.14 + message-then-summary deliver the message first followed by a summary
1.15 + message
1.16 +
1.17 + summary-then-message deliver a summary first followed by the message
1.18 +
1.19 + summary-only deliver only a summary of the message
1.20
1.21 participating
1.22 -------------
1.23 @@ -72,3 +75,31 @@
1.24 recipients will be handled in other ways. Thus, initial non-participation must
1.25 be defined by initialising this setting to "no" for all eligible users, if
1.26 this is the general policy on initial calendar system participation.
1.27 +
1.28 +permitted_times
1.29 +---------------
1.30 +
1.31 +Default: (none)
1.32 +Alternatives: (see below)
1.33 +
1.34 +Define the time values at which events can be scheduled. In its simplest form,
1.35 +this indicates the resolution of a calendar for a participant supporting this
1.36 +setting, with the given minute values being those allowed for the start and
1.37 +end of an event. This setting requires a value of one of the following forms:
1.38 +
1.39 + <minute values>
1.40 + <hour values>:<minute values>
1.41 + <hour values>:<minute values>:<second values>
1.42 +
1.43 +Each list of values is a comma-separated collection of permissible values for
1.44 +the unit of time being constrained. Any unspecified list is taken to permit
1.45 +all normally permissible values for that unit of time. For example:
1.46 +
1.47 + 0,15,30,45 every 15 minutes from the start of each hour
1.48 + 10,12,14,16:0,20,40 every 20 minutes from 10:00 until 16:40 inclusive
1.49 + 12::0,30 every 30 seconds from the start of each minute during
1.50 + the period from 12:00:00 until 12:59:30 inclusive
1.51 +
1.52 +The purpose of this setting is not necessarily to impose availability
1.53 +constraints but instead to impose a "grid" to which event start and end points
1.54 +shall be "locked".
2.1 --- a/imiptools/client.py Mon Aug 31 15:44:46 2015 +0200
2.2 +++ b/imiptools/client.py Mon Aug 31 18:09:31 2015 +0200
2.3 @@ -24,7 +24,7 @@
2.4 from imiptools.data import Object, get_address, get_uri, get_window_end, \
2.5 is_new_object, make_freebusy, to_part, \
2.6 uri_dict, uri_items, uri_values
2.7 -from imiptools.dates import check_resolution, format_datetime, get_default_timezone, \
2.8 +from imiptools.dates import check_permitted_values, format_datetime, get_default_timezone, \
2.9 get_timestamp, to_timezone
2.10 from imiptools.period import can_schedule, remove_period, \
2.11 remove_additional_periods, remove_affected_period, \
2.12 @@ -89,7 +89,7 @@
2.13 def have_manager(self):
2.14 return MANAGER_INTERFACE
2.15
2.16 - def get_scheduling_resolution(self):
2.17 + def get_permitted_values(self):
2.18
2.19 """
2.20 Decode a specification of one of the following forms...
2.21 @@ -102,11 +102,11 @@
2.22 """
2.23
2.24 prefs = self.get_preferences()
2.25 - resolution = prefs and prefs.get("scheduling_resolution")
2.26 - if resolution:
2.27 + permitted_values = prefs and prefs.get("permitted_times")
2.28 + if permitted_values:
2.29 try:
2.30 l = []
2.31 - for component in resolution.split(":")[:3]:
2.32 + for component in permitted_values.split(":")[:3]:
2.33 if component:
2.34 l.append(map(int, component.split(",")))
2.35 else:
2.36 @@ -424,8 +424,8 @@
2.37
2.38 "Check the object against any scheduling constraints."
2.39
2.40 - resolution = self.get_scheduling_resolution()
2.41 - if not resolution:
2.42 + permitted_values = self.get_permitted_values()
2.43 + if not permitted_values:
2.44 return None
2.45
2.46 invalid = []
2.47 @@ -433,8 +433,8 @@
2.48 for period in self.obj.get_periods(self.get_tzid()):
2.49 start = period.get_start()
2.50 end = period.get_end()
2.51 - start_errors = check_resolution(start, resolution)
2.52 - end_errors = check_resolution(end, resolution)
2.53 + start_errors = check_permitted_values(start, permitted_values)
2.54 + end_errors = check_permitted_values(end, permitted_values)
2.55 if start_errors or end_errors:
2.56 invalid.append((period.origin, start_errors, end_errors))
2.57
2.58 @@ -444,8 +444,8 @@
2.59
2.60 "Correct the object according to any scheduling constraints."
2.61
2.62 - resolution = self.get_scheduling_resolution()
2.63 - return resolution and self.obj.correct_object(self.get_tzid(), resolution)
2.64 + permitted_values = self.get_permitted_values()
2.65 + return permitted_values and self.obj.correct_object(self.get_tzid(), permitted_values)
2.66
2.67 # Object retrieval.
2.68
3.1 --- a/imiptools/data.py Mon Aug 31 15:44:46 2015 +0200
3.2 +++ b/imiptools/data.py Mon Aug 31 18:09:31 2015 +0200
3.3 @@ -22,7 +22,7 @@
3.4 from bisect import bisect_left
3.5 from datetime import date, datetime, timedelta
3.6 from email.mime.text import MIMEText
3.7 -from imiptools.dates import check_resolution, correct_datetime, \
3.8 +from imiptools.dates import check_permitted_values, correct_datetime, \
3.9 format_datetime, get_datetime, \
3.10 get_datetime_item as get_item_from_datetime, \
3.11 get_datetime_tzid, \
3.12 @@ -396,7 +396,7 @@
3.13
3.14 return old_values != set(self.get_date_values("RDATE"))
3.15
3.16 - def correct_object(self, tzid, resolution):
3.17 + def correct_object(self, tzid, permitted_values):
3.18
3.19 "Correct the object's period details."
3.20
3.21 @@ -406,8 +406,8 @@
3.22 for period in self.get_periods(tzid):
3.23 start = period.get_start()
3.24 end = period.get_end()
3.25 - start_errors = check_resolution(start, resolution)
3.26 - end_errors = check_resolution(end, resolution)
3.27 + start_errors = check_permitted_values(start, permitted_values)
3.28 + end_errors = check_permitted_values(end, permitted_values)
3.29
3.30 if not (start_errors or end_errors):
3.31 if period.origin == "RDATE":
3.32 @@ -415,9 +415,9 @@
3.33 continue
3.34
3.35 if start_errors:
3.36 - start = correct_datetime(start, resolution)
3.37 + start = correct_datetime(start, permitted_values)
3.38 if end_errors:
3.39 - end = correct_datetime(end, resolution)
3.40 + end = correct_datetime(end, permitted_values)
3.41 period = RecurringPeriod(start, end, period.tzid, period.origin, period.get_start_attr(), period.get_end_attr())
3.42
3.43 if period.origin == "DTSTART":
4.1 --- a/imiptools/dates.py Mon Aug 31 15:44:46 2015 +0200
4.2 +++ b/imiptools/dates.py Mon Aug 31 18:09:31 2015 +0200
4.3 @@ -476,14 +476,14 @@
4.4 class ValidityError(Exception):
4.5 pass
4.6
4.7 -def check_resolution(dt, resolution):
4.8 +def check_permitted_values(dt, permitted_values):
4.9
4.10 - "Check the datetime 'dt' against the 'resolution' list."
4.11 + "Check the datetime 'dt' against the 'permitted_values' list."
4.12
4.13 if not isinstance(dt, datetime):
4.14 raise ValidityError
4.15
4.16 - hours, minutes, seconds = resolution
4.17 + hours, minutes, seconds = permitted_values
4.18 errors = []
4.19
4.20 if hours and dt.hour not in hours:
4.21 @@ -495,19 +495,19 @@
4.22
4.23 return errors
4.24
4.25 -def correct_datetime(dt, resolution):
4.26 +def correct_datetime(dt, permitted_values):
4.27
4.28 - "Correct 'dt' using the given 'resolution' details."
4.29 + "Correct 'dt' using the given 'permitted_values' details."
4.30
4.31 - carry, hour, minute, second = correct_value((dt.hour, dt.minute, dt.second), resolution)
4.32 + carry, hour, minute, second = correct_value((dt.hour, dt.minute, dt.second), permitted_values)
4.33 return datetime(dt.year, dt.month, dt.day, hour, minute, second, dt.microsecond, dt.tzinfo) + \
4.34 (carry and timedelta(1) or timedelta(0))
4.35
4.36 -def correct_value(value, resolution):
4.37 +def correct_value(value, permitted_values):
4.38
4.39 """
4.40 Correct the given (hour, minute, second) tuple 'value' according to the
4.41 - 'resolution' details.
4.42 + 'permitted_values' details.
4.43 """
4.44
4.45 limits = 23, 59, 59
4.46 @@ -517,7 +517,7 @@
4.47
4.48 # Find invalid values and reset all following values.
4.49
4.50 - for v, values, limit in zip(value, resolution, limits):
4.51 + for v, values, limit in zip(value, permitted_values, limits):
4.52 if reset:
4.53 if values:
4.54 v = values[0]
4.55 @@ -537,7 +537,7 @@
4.56 # significant values if the next valid value is the first in the appropriate
4.57 # series.
4.58
4.59 - for v, values, limit in zip(value, resolution, limits)[::-1]:
4.60 + for v, values, limit in zip(value, permitted_values, limits)[::-1]:
4.61 if carry:
4.62 v += 1
4.63 if v > limit:
5.1 --- a/tests/test_resource_invitation_constraints.sh Mon Aug 31 15:44:46 2015 +0200
5.2 +++ b/tests/test_resource_invitation_constraints.sh Mon Aug 31 18:09:31 2015 +0200
5.3 @@ -21,7 +21,7 @@
5.4 mkdir -p "$PREFS/$USER"
5.5 echo 'Europe/Oslo' > "$PREFS/$USER/TZID"
5.6 echo 'share' > "$PREFS/$USER/freebusy_sharing"
5.7 -echo '10,12,14,16,18:0,15,30,45' > "$PREFS/$USER/scheduling_resolution"
5.8 +echo '10,12,14,16,18:0,15,30,45' > "$PREFS/$USER/permitted_times"
5.9
5.10 "$RESOURCE_SCRIPT" $ARGS < "$TEMPLATES/fb-request-sauna-all.txt" 2>> $ERROR \
5.11 | "$SHOWMAIL" \