1.1 --- a/imiptools/client.py Wed Aug 12 22:40:50 2015 +0200
1.2 +++ b/imiptools/client.py Fri Aug 14 00:44:53 2015 +0200
1.3 @@ -81,6 +81,39 @@
1.4 prefs = self.get_preferences()
1.5 return prefs and prefs.get("freebusy_messages") == "notify" or False
1.6
1.7 + def get_scheduling_resolution(self):
1.8 +
1.9 + """
1.10 + Decode a specification of one of the following forms...
1.11 +
1.12 + <minute values>
1.13 + <hour values>:<minute values>
1.14 + <hour values>:<minute values>:<second values>
1.15 +
1.16 + ...with each list of values being comma-separated.
1.17 + """
1.18 +
1.19 + prefs = self.get_preferences()
1.20 + resolution = prefs and prefs.get("scheduling_resolution")
1.21 + if resolution:
1.22 + try:
1.23 + l = []
1.24 + for component in resolution.split(":")[:3]:
1.25 + if component:
1.26 + l.append(map(int, component.split(",")))
1.27 + else:
1.28 + l.append(None)
1.29 +
1.30 + # NOTE: Should probably report an error somehow.
1.31 +
1.32 + except ValueError:
1.33 + return None
1.34 + else:
1.35 + l = (len(l) < 2 and [None] or []) + l + (len(l) < 3 and [None] or [])
1.36 + return l
1.37 + else:
1.38 + return None
1.39 +
1.40 # Common operations on calendar data.
1.41
1.42 def update_attendees(self, obj, attendees, removed):
1.43 @@ -377,6 +410,50 @@
1.44
1.45 return False
1.46
1.47 + # Constraint application on event periods.
1.48 +
1.49 + class ValidityError(Exception):
1.50 + pass
1.51 +
1.52 + def check_object(self):
1.53 +
1.54 + "Check the object against any scheduling constraints."
1.55 +
1.56 + resolution = self.get_scheduling_resolution()
1.57 + if not resolution:
1.58 + return None
1.59 +
1.60 + tzid = self.get_tzid()
1.61 + invalid = []
1.62 +
1.63 + for period in self.obj.get_periods(tzid):
1.64 + start = period.get_start()
1.65 + end = period.get_end()
1.66 + start_result = self.check_resolution(start, resolution)
1.67 + end_result = self.check_resolution(end, resolution)
1.68 + if start_result or end_result:
1.69 + invalid.append((period.origin, start_result, end_result))
1.70 +
1.71 + return invalid
1.72 +
1.73 + def check_resolution(self, dt, resolution):
1.74 +
1.75 + "Check the datetime 'dt' against the 'resolution' list."
1.76 +
1.77 + if not isinstance(dt, datetime):
1.78 + raise ValidityError
1.79 +
1.80 + hours, minutes, seconds = resolution
1.81 +
1.82 + if hours and dt.hour not in hours:
1.83 + return "hour"
1.84 + if minutes and dt.minute not in minutes:
1.85 + return "minute"
1.86 + if seconds and dt.second not in seconds:
1.87 + return "second"
1.88 +
1.89 + return None
1.90 +
1.91 # Object retrieval.
1.92
1.93 def get_stored_object_version(self):