summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Utils.py
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-02-05 12:13:20 -0500
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-02-14 15:12:20 -0500
commit9bec4d6bbab599bee72256c7e09fe214cb849a1b (patch)
treecd2c5dac3463e6f505b0d522036ee7ac204c3276 /src/lib/Bcfg2/Utils.py
parente989e62b24479fac99e607d9e4fb3a292bd20418 (diff)
downloadbcfg2-9bec4d6bbab599bee72256c7e09fe214cb849a1b.tar.gz
bcfg2-9bec4d6bbab599bee72256c7e09fe214cb849a1b.tar.bz2
bcfg2-9bec4d6bbab599bee72256c7e09fe214cb849a1b.zip
abstracted similar digit range classes in POSIXUsers/GroupPatterns into Bcfg2.Utils
Diffstat (limited to 'src/lib/Bcfg2/Utils.py')
-rw-r--r--src/lib/Bcfg2/Utils.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/lib/Bcfg2/Utils.py b/src/lib/Bcfg2/Utils.py
new file mode 100644
index 000000000..ba17e1a63
--- /dev/null
+++ b/src/lib/Bcfg2/Utils.py
@@ -0,0 +1,67 @@
+""" Miscellaneous useful utility functions, classes, etc., that are
+used by both client and server. Stuff that doesn't fit anywhere
+else. """
+
+from Bcfg2.Compat import any # pylint: disable=W0622
+
+
+class PackedDigitRange(object):
+ """ Representation of a set of integer ranges. A range is
+ described by a comma-delimited string of integers and ranges,
+ e.g.::
+
+ 1,10-12,15-20
+
+ Ranges are inclusive on both bounds, and may include 0. Negative
+ numbers are not supported."""
+
+ def __init__(self, *ranges):
+ """ May be instantiated in one of two ways::
+
+ PackedDigitRange(<comma-delimited list of ranges>)
+
+ Or::
+
+ PackedDigitRange(<int_or_range>[, <int_or_range>[, ...]])
+
+ E.g., both of the following are valid::
+
+ PackedDigitRange("1-5,7, 10-12")
+ PackedDigitRange("1-5", 7, "10-12")
+ """
+ self.ranges = []
+ self.ints = []
+ self.str = ",".join(str(r) for r in ranges)
+ if len(ranges) == 1 and "," in ranges[0]:
+ ranges = ranges[0].split(",")
+ for item in ranges:
+ item = str(item).strip()
+ if item.endswith("-"):
+ self.ranges.append((int(item[:-1]), None))
+ elif '-' in str(item):
+ self.ranges.append(tuple(int(x) for x in item.split('-')))
+ else:
+ self.ints.append(int(item))
+
+ def includes(self, other):
+ """ Return True if ``other`` is included in this range.
+ Functionally equivalent to ``other in range``, which should be
+ used instead. """
+ return other in self
+
+ def __contains__(self, other):
+ other = int(other)
+ if other in self.ints:
+ return True
+ return any((end is None and other >= start) or
+ (end is not None and other >= start and other <= end)
+ for start, end in self.ranges)
+
+ def __repr__(self):
+ return "%s:%s" % (self.__class__.__name__, str(self))
+
+ def __str__(self):
+ return "[%s]" % self.str
+
+ def __len__(self):
+ return sum(r[1] - r[0] + 1 for r in self.ranges) + len(self.ints)