change the logic of clipping leases
[plcapi.git] / PLC / LeaseFilter.py
index 84f84b7..de340ea 100644 (file)
@@ -21,18 +21,20 @@ class LeaseFilter(Filter):
     # general notes on input parameters
     # int_timestamp: number of seconds since the epoch
     # str_timestamp: see Timestamp.sql_validate
-    # timeslot: a tuple (from, until), each being either int_timestamp or
+    # timeslot: a list [from, until], each being either int_timestamp or
     # str_timestamp
 
     local_fields = {
         'alive': Mixed(
             Parameter(int, "int_timestamp: leases alive at that time"),
             Parameter(str, "str_timestamp: leases alive at that time"),
-            Parameter(tuple, "timeslot: the leases alive during this timeslot")),
-        'clip':  Mixed(
+            Parameter(list, "timeslot: the leases alive during this timeslot"),
+            ),
+        'clip': Mixed(
             Parameter(int, "int_timestamp: leases alive after that time"),
             Parameter(str, "str_timestamp: leases alive after that time"),
-            Parameter(tuple, "timeslot: the leases alive during this timeslot")),
+            Parameter(list, "timeslot: the leases alive during this timeslot"),
+            ),
         ########## macros
         # {'day' : 0} : all leases from today and on
         # {'day' : 1} : all leases today (localtime at the myplc)
@@ -62,12 +64,11 @@ class LeaseFilter(Filter):
     # basic SQL utilities
     @staticmethod
     def sql_time_intersect(f1, u1, f2, u2):
-        # either f2 is in [f1,u1], or u2 is in [f1,u1], or f2<=f1<=u1<=u2
+        # either f2 is in [f1,u1[, or u2 is in ]f1,u1], or f2<=f1<u1<=u2
         return (
-            "(({f1} <= {f2}) AND ({f2} <= {u1})) "
-            "OR (({f1} <= {u2}) AND ({u2} <= {u1})) "
-            "OR (({f2}<={f1}) AND ({u1}<={u2}))"
-            .format(f1=f1, u1=u1, f2=f2, u2=u2))
+            f"(({f1} <= {f2}) AND ({f2} < {u1})) "
+            f"OR (({f1} < {u2}) AND ({u2} <= {u1})) "
+            f"OR (({f2}<={f1}) AND ({u1}<={u2}))")
 
     @staticmethod
     def time_in_range(timestamp, f1, u1):
@@ -77,14 +78,12 @@ class LeaseFilter(Filter):
     @staticmethod
     def sql_time_in_range(timestamp, f1, u1):
         # is timestamp in [f1, u1]
-        return (
-            "(({f1} <= {timestamp}) AND ({timestamp} <= {u1}))"
-            .format(timestamp=timestamp, f1=f1, u1=u1))
+        return f"(({f1} <= {timestamp}) AND ({timestamp} <= {u1}))"
 
     @staticmethod
     def sql_timeslot_after(f1, u1, mark):
         # is the lease alive after mark, i.e. u1 >= mark
-        return "({u1} >= {mark})".format(u1=u1, mark=mark)
+        return f"({u1} >= {mark})"
 
     # hooks for the local fields
     def sql_alive(self, alive):
@@ -92,27 +91,25 @@ class LeaseFilter(Filter):
             # the lease is alive at that time if from <= alive <= until
             alive = LeaseFilter.quote(alive)
             return LeaseFilter.sql_time_in_range(alive, 't_from', 't_until')
-        elif isinstance(alive, tuple):
+        elif isinstance(alive, (tuple, list)):
             (f, u) = alive
             f = LeaseFilter.quote(f)
             u = LeaseFilter.quote(u)
             return LeaseFilter.sql_time_intersect(f, u, 't_from', 't_until')
         else:
-            raise PLCInvalidArgument("LeaseFilter: alive field {}"
-                                     .format(alive))
+            raise PLCInvalidArgument(f"LeaseFilter: alive field {alive}")
 
     def sql_clip(self, clip):
         if isinstance(clip, int) or isinstance(clip, str):
             start = LeaseFilter.quote(clip)
             return LeaseFilter.sql_timeslot_after('t_from', 't_until', start)
-        elif isinstance(clip, tuple):
+        elif isinstance(clip, (tuple, list)):
             (f, u) = clip
             f = LeaseFilter.quote(f)
             u = LeaseFilter.quote(u)
             return LeaseFilter.sql_time_intersect(f, u, 't_from', 't_until')
         else:
-            raise PLCInvalidArgument("LeaseFilter: clip field {}"
-                                     .format(clip))
+            raise PLCInvalidArgument(f"LeaseFilter: clip field {clip}")
 
     # the whole key to implementing day is to compute today's beginning
     def today_start(self):
@@ -155,14 +152,14 @@ class LeaseFilter(Filter):
             try:
                 # locate hook function associated with key
                 method = LeaseFilter.__dict__['sql_' + k]
-                where_part += " {} {}({})"\
-                              .format(self.join_with,
-                                      self.negation[k],
-                                      method(self, self.local[k]))
+                where_part += (
+                    f" {self.join_with} {self.negation[k]}"
+                    f"({method(self, self.local[k])})"
+                )
             except Exception as e:
                 raise PLCInvalidArgument(
-                    "LeaseFilter: something wrong with filter"
-                    "key {}, val was {} -- {}".format(k, v, e))
+                    f"LeaseFilter: something wrong with filter "
+                    f"key {k}, value was {v} -- {e}")
         return (where_part, clip_part)
 
 # xxx not sure where this belongs yet