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