1.1 --- a/imiptools/client.py Mon Oct 26 19:46:49 2015 +0100
1.2 +++ b/imiptools/client.py Tue Oct 27 00:05:46 2015 +0100
1.3 @@ -233,14 +233,16 @@
1.4
1.5 return None
1.6
1.7 - def get_periods(self, obj):
1.8 + def get_periods(self, obj, explicit_only=False):
1.9
1.10 """
1.11 Return periods for the given 'obj'. Interpretation of periods can depend
1.12 - on the time zone, which is obtained for the current user.
1.13 + on the time zone, which is obtained for the current user. If
1.14 + 'explicit_only' is set to a true value, only explicit periods will be
1.15 + returned, not rule-based periods.
1.16 """
1.17
1.18 - return obj.get_periods(self.get_tzid(), self.get_window_end())
1.19 + return obj.get_periods(self.get_tzid(), not explicit_only and self.get_window_end() or None)
1.20
1.21 # Store operations.
1.22
1.23 @@ -880,11 +882,9 @@
1.24 invalid = []
1.25
1.26 for period in self.obj.get_periods(self.get_tzid()):
1.27 - start = period.get_start()
1.28 - end = period.get_end()
1.29 - start_errors = check_permitted_values(start, permitted_values)
1.30 - end_errors = check_permitted_values(end, permitted_values)
1.31 - if start_errors or end_errors:
1.32 + errors = period.check_permitted(permitted_values)
1.33 + if errors:
1.34 + start_errors, end_errors = errors
1.35 invalid.append((period.origin, start_errors, end_errors))
1.36
1.37 return invalid
1.38 @@ -896,6 +896,16 @@
1.39 permitted_values = self.get_permitted_values()
1.40 return permitted_values and self.obj.correct_object(self.get_tzid(), permitted_values)
1.41
1.42 + def correct_period(self, period):
1.43 +
1.44 + "Correct 'period' according to any scheduling constraints."
1.45 +
1.46 + permitted_values = self.get_permitted_values()
1.47 + if not permitted_values:
1.48 + return period
1.49 + else:
1.50 + return period.get_corrected(permitted_values)
1.51 +
1.52 # Object retrieval.
1.53
1.54 def get_stored_object_version(self):
2.1 --- a/imiptools/period.py Mon Oct 26 19:46:49 2015 +0100
2.2 +++ b/imiptools/period.py Tue Oct 27 00:05:46 2015 +0100
2.3 @@ -129,6 +129,10 @@
2.4 return Comparable(ifnone(self.get_end_point(), EndOfTime())) > Comparable(ifnone(other.get_start_point(), StartOfTime())) and \
2.5 Comparable(ifnone(self.get_start_point(), StartOfTime())) < Comparable(ifnone(other.get_end_point(), EndOfTime()))
2.6
2.7 + def within(self, other):
2.8 + return Comparable(ifnone(self.get_start_point(), StartOfTime())) >= Comparable(ifnone(other.get_start_point(), StartOfTime())) and \
2.9 + Comparable(ifnone(self.get_end_point(), EndOfTime())) <= Comparable(ifnone(other.get_end_point(), EndOfTime()))
2.10 +
2.11 def get_key(self):
2.12 return self.get_start(), self.get_end()
2.13
2.14 @@ -239,9 +243,18 @@
2.15
2.16 # Value correction methods.
2.17
2.18 - def get_corrected(self, permitted_values):
2.19 + def with_duration(self, duration):
2.20
2.21 - "Return a corrected version of this period."
2.22 + """
2.23 + Return a version of this period with the same start point but with the
2.24 + given 'duration'.
2.25 + """
2.26 +
2.27 + return self.make_corrected(self.get_start(), self.get_start() + duration)
2.28 +
2.29 + def check_permitted(self, permitted_values):
2.30 +
2.31 + "Check the period against the given 'permitted_values'."
2.32
2.33 start = self.get_start()
2.34 end = self.get_end()
2.35 @@ -249,8 +262,21 @@
2.36 end_errors = check_permitted_values(end, permitted_values)
2.37
2.38 if not (start_errors or end_errors):
2.39 + return None
2.40 +
2.41 + return start_errors, end_errors
2.42 +
2.43 + def get_corrected(self, permitted_values):
2.44 +
2.45 + "Return a corrected version of this period."
2.46 +
2.47 + errors = self.check_permitted(permitted_values)
2.48 +
2.49 + if not errors:
2.50 return self
2.51
2.52 + start_errors, end_errors = errors
2.53 +
2.54 if start_errors:
2.55 start = correct_datetime(start, permitted_values)
2.56 if end_errors: