From 3261f7cf5314a76b85884942d077146fe8f8fc24 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Thu, 27 Jun 2013 10:35:06 -0400 Subject: Options: migrated common utils to new parser --- src/lib/Bcfg2/Utils.py | 67 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/lib/Bcfg2/Utils.py b/src/lib/Bcfg2/Utils.py index d087f4f87..5d8204460 100644 --- a/src/lib/Bcfg2/Utils.py +++ b/src/lib/Bcfg2/Utils.py @@ -2,12 +2,16 @@ used by both client and server. Stuff that doesn't fit anywhere else. """ +import os +import re +import sys import shlex import fcntl +import select import logging import threading import subprocess -from Bcfg2.Compat import any # pylint: disable=W0622 +from Bcfg2.Compat import input, any # pylint: disable=W0622 class ClassName(object): @@ -250,3 +254,64 @@ class Executor(object): finally: if timeout is not None: timer.cancel() + + +def list2range(lst): + ''' convert a list of integers to a set of human-readable ranges. e.g.: + + [1, 2, 3, 6, 9, 10, 11] -> "[1-3,6,9-11]" ''' + ilst = sorted(int(i) for i in lst) + ranges = [] + start = None + last = None + for i in ilst: + if not last or i != last + 1: + if start: + if start == last: + ranges.append(str(start)) + else: + ranges.append("%d-%d" % (start, last)) + start = i + last = i + if start: + if start == last: + ranges.append(str(start)) + else: + ranges.append("%d-%d" % (start, last)) + if not ranges: + return "" + elif len(ranges) > 1 or "-" in ranges[0]: + return "[%s]" % ",".join(ranges) + else: + # only one range consisting of only a single number + return ranges[0] + + +def hostnames2ranges(hostnames): + ''' convert a list of hostnames to a set of human-readable ranges. e.g.: + + ["foo1.example.com", "foo2.example.com", "foo3.example.com", + "foo6.example.com"] -> ["foo[1-3,6].example.com"]''' + hosts = {} + hostre = re.compile(r'(\w+?)(\d+)(\..*)$') + for host in hostnames: + match = hostre.match(host) + if match: + key = (match.group(1), match.group(3)) + try: + hosts[key].append(match.group(2)) + except KeyError: + hosts[key] = [match.group(2)] + + ranges = [] + for name, nums in hosts.items(): + ranges.append(name[0] + list2range(nums) + name[1]) + return ranges + + +def safe_input(msg): + """ input() that flushes the input buffer before accepting input """ + # flush input buffer + while len(select.select([sys.stdin.fileno()], [], [], 0.0)[0]) > 0: + os.read(sys.stdin.fileno(), 4096) + return input(msg) -- cgit v1.2.3-1-g7c22