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 14:56:23 -0500
commit9d0e6991fc23c073efc0db6bf10e1081f6725e55 (patch)
treed59c0b3ce496aef72dd18812960fc2e101dab8e4 /src/lib/Bcfg2/Utils.py
parentcfa4ce0a6fe82ed8578fe4668998012ad3833e05 (diff)
downloadbcfg2-9d0e6991fc23c073efc0db6bf10e1081f6725e55.tar.gz
bcfg2-9d0e6991fc23c073efc0db6bf10e1081f6725e55.tar.bz2
bcfg2-9d0e6991fc23c073efc0db6bf10e1081f6725e55.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)