mirror of
https://pagure.io/fedora-infra/ansible.git
synced 2026-03-19 19:46:38 +08:00
updates+uptimes: Minor UI tweaks, less hacky sort.
Signed-off-by: James Antill <james@and.org>
This commit is contained in:
@@ -50,9 +50,6 @@ conf_term_keyword = 'underline'
|
||||
conf_term_time = 'underline'
|
||||
conf_term_title = 'italic'
|
||||
|
||||
# Use version cmp() for hostnames.
|
||||
conf_verscmp = True
|
||||
|
||||
# Use _ instead of , for number seperator.
|
||||
conf_num_sep_ = False
|
||||
|
||||
@@ -152,7 +149,7 @@ def _user_conf_line(line):
|
||||
|
||||
key = 'conf_' + key.strip().lower()
|
||||
if key not in globals():
|
||||
print(" Error: Configuration not found: ", key, file=sys.stderr)
|
||||
print(" Warn: Configuration not found: ", key, file=sys.stderr)
|
||||
return
|
||||
|
||||
if False: pass
|
||||
@@ -189,42 +186,85 @@ def _user_conf_line(line):
|
||||
print(" Error: Configuration ", key,'bad op', file=sys.stderr)
|
||||
return
|
||||
|
||||
# This isn't fast but it's SMALL:
|
||||
# Sort as: ABC1, ABC2, ABC10b, ...
|
||||
def verscmp(x, y):
|
||||
if not conf_verscmp:
|
||||
if x == y:
|
||||
return 0
|
||||
if x > y:
|
||||
return 1
|
||||
return -1
|
||||
|
||||
xc = re.split(r'(\d+|\W+)', x)
|
||||
yc = re.split(r'(\d+|\W+)', y)
|
||||
while xc and yc:
|
||||
if xc[0] == yc[0]:
|
||||
xc.pop(0)
|
||||
yc.pop(0)
|
||||
continue
|
||||
# This is kind of fast and kind of small. No re, and no allocation.
|
||||
# Sort as: 0, 00, 000, 01, 011, 1, 11, a01, a1, z01, z1, etc.
|
||||
def natcmp(x, y):
|
||||
""" Natural sort string comparison.
|
||||
https://en.wikipedia.org/wiki/Natural_sort_order
|
||||
Aka. vercmp() """
|
||||
|
||||
if xc[0].isnumeric():
|
||||
if not yc[0].isnumeric():
|
||||
return 1
|
||||
nx = int(xc[0])
|
||||
ny = int(yc[0])
|
||||
if nx != ny: # don't make 0 == 00 ... we aren't rpm.
|
||||
return nx - ny
|
||||
elif yc[0].isnumeric():
|
||||
def _cmp_xy_mix(): # One is a digit, the other isn't.
|
||||
if inum is not None: # 0/1 vs. x/.
|
||||
return 1
|
||||
if x[i] > y[i]:
|
||||
return 1
|
||||
else:
|
||||
return -1
|
||||
|
||||
# Neither numeric, but also 0 == 00 BS
|
||||
if xc[0] > yc[0]:
|
||||
return 1
|
||||
inum = None
|
||||
check_zeros = False
|
||||
for i in range(min(len(x), len(y))):
|
||||
if x[i] in "0123456789" and y[i] not in "0123456789":
|
||||
return _cmp_xy_mix()
|
||||
if x[i] not in "0123456789" and y[i] in "0123456789":
|
||||
return _cmp_xy_mix()
|
||||
|
||||
if x[i] in "0123456789": # Both are digits...
|
||||
if inum is None:
|
||||
check_zeros = True
|
||||
inum = 0
|
||||
|
||||
if check_zeros: # Leading zeros... (0 < 00 < 01 < 011 < 1 < 11)
|
||||
if x[i] == '0' and y[i] == '0':
|
||||
continue
|
||||
elif x[i] == '0':
|
||||
return -1
|
||||
elif y[i] == '0':
|
||||
return 1
|
||||
else:
|
||||
check_zeros = False
|
||||
|
||||
# If we are already in a number, we only care about the length or
|
||||
# the first digit that is different.
|
||||
if inum != 0:
|
||||
continue
|
||||
|
||||
if x[i] == y[i]:
|
||||
continue
|
||||
|
||||
# Non-zero first digit, Eg. 7 < 9
|
||||
inum = int(x[i]) - int(y[i])
|
||||
continue
|
||||
|
||||
# Both are not digits...
|
||||
if inum is not None and inum != 0:
|
||||
return inum
|
||||
inum = None
|
||||
|
||||
# Can be equal
|
||||
if x[i] > y[i]:
|
||||
return 1
|
||||
if x[i] < y[i]:
|
||||
return -1
|
||||
|
||||
if len(x) > len(y):
|
||||
if inum is not None and inum != 0 and x[i+1] not in "0123456789":
|
||||
return inum
|
||||
return 1
|
||||
if len(x) < len(y):
|
||||
if inum is not None and inum != 0 and y[i+1] not in "0123456789":
|
||||
return inum
|
||||
return -1
|
||||
return len(xc) - len(yc)
|
||||
|
||||
if inum is None: # Same length, not in a num.
|
||||
assert x == y
|
||||
return 0 # So the strings are equal.
|
||||
|
||||
return inum
|
||||
|
||||
|
||||
class VerscmpString():
|
||||
class NatCmp():
|
||||
__slots__ = ['s',]
|
||||
def __init__(self, s):
|
||||
self.s = s
|
||||
@@ -236,16 +276,14 @@ class VerscmpString():
|
||||
return self.s == other.s
|
||||
|
||||
def __gt__(self, other):
|
||||
ret = verscmp(self.s, other.s)
|
||||
ret = natcmp(self.s, other.s)
|
||||
if ret > 0:
|
||||
return True
|
||||
if False and ret < 0:
|
||||
return False
|
||||
return False
|
||||
|
||||
# Given a list of strings, sort them using verscmp()
|
||||
def _verscmp_strings(xs):
|
||||
for ret in sorted(VerscmpString(x) for x in xs):
|
||||
# Given a list of strings, sort them using natcmp()
|
||||
def nat_sorted(xs):
|
||||
for ret in sorted(NatCmp(x) for x in xs):
|
||||
yield ret.s
|
||||
|
||||
|
||||
@@ -490,7 +528,7 @@ class Host():
|
||||
return True
|
||||
|
||||
def __gt__(self, other):
|
||||
ret = verscmp(self.name, other.name)
|
||||
ret = natcmp(self.name, other.name)
|
||||
if ret > 0:
|
||||
return True
|
||||
if ret < 0:
|
||||
@@ -1337,7 +1375,7 @@ def _cmd_stats(args):
|
||||
max_nhosts_lvl_2 = 0
|
||||
max_update_lvl_2 = 0
|
||||
max_uptime_lvl_2 = 0
|
||||
for osi in _verscmp_strings(osdata['hosts']):
|
||||
for osi in nat_sorted(osdata['hosts']):
|
||||
if '/' not in osi:
|
||||
max_nhosts_lvl_1 = max(max_nhosts_lvl_1, osdata['hosts'][osi])
|
||||
supd = osdata['updates'][osi] / osdata['hosts'][osi]
|
||||
@@ -1385,7 +1423,7 @@ def _cmd_stats(args):
|
||||
suf = _ui_t_high(suf)
|
||||
return uiosi, uinhosts, uiupdates, uiuptimes, uinpdates, uinptimes, suf
|
||||
|
||||
for osi in _verscmp_strings(osdata['hosts']):
|
||||
for osi in nat_sorted(osdata['hosts']):
|
||||
if '/' not in osi:
|
||||
if len(osdata['vers'][osi]) == 1:
|
||||
subprefix = ''
|
||||
@@ -2003,7 +2041,7 @@ utf8: {conf_utf8}
|
||||
{_conf_utf8_diff_os} = Different OS information, but machine id is the same
|
||||
{_conf_utf8_diff_hw} = Machine id is different
|
||||
|
||||
{_hlp_als("host")}
|
||||
{_hlp_als("hosts")}
|
||||
Eg. {prog} {args.hcmd}
|
||||
{prog} {args.hcmd} 'batcave*'
|
||||
{prog} {args.hcmd} 'batcave*' 'noc*'
|
||||
|
||||
Reference in New Issue
Block a user