Various changes.
[python_utils.git] / string_utils.py
index 623ae45f03e6eb12c608f966b421ba9c5495b0e9..aca4a5e3bfd9f49efa9a329b06addd9af5ffaa0a 100644 (file)
@@ -791,6 +791,9 @@ def extract_mac_address(in_str: Any, *, separator: str = ":") -> Optional[str]:
     >>> extract_mac_address(' MAC Address: 34:29:8F:12:0D:2F')
     '34:29:8F:12:0D:2F'
 
+    >>> extract_mac_address('? (10.0.0.30) at d8:5d:e2:34:54:86 on em0 expires in 1176 seconds [ethernet]')
+    'd8:5d:e2:34:54:86'
+
     """
     if not is_full_string(in_str):
         return None
@@ -1461,10 +1464,14 @@ def to_bitstring(txt: str, *, delimiter='', encoding='utf-8', errors='surrogatep
     >>> to_bitstring('test', delimiter=' ')
     '01110100 01100101 01110011 01110100'
 
+    >>> to_bitstring(b'test')
+    '01110100011001010111001101110100'
+
     """
+    etxt = to_ascii(txt)
     bits = bin(
         int.from_bytes(
-            txt.encode(encoding, errors),
+            etxt,
             'big'
         )
     )
@@ -1496,6 +1503,38 @@ def from_bitstring(bits: str, encoding='utf-8', errors='surrogatepass') -> str:
     return n.to_bytes((n.bit_length() + 7) // 8, 'big').decode(encoding, errors) or '\0'
 
 
+def ip_v4_sort_key(txt: str) -> Tuple[int]:
+    """Turn an IPv4 address into a tuple for sorting purposes.
+
+    >>> ip_v4_sort_key('10.0.0.18')
+    (10, 0, 0, 18)
+
+    >>> ips = ['10.0.0.10', '100.0.0.1', '1.2.3.4', '10.0.0.9']
+    >>> sorted(ips, key=lambda x: ip_v4_sort_key(x))
+    ['1.2.3.4', '10.0.0.9', '10.0.0.10', '100.0.0.1']
+
+    """
+    if not is_ip_v4(txt):
+        print(f"not IP: {txt}")
+        return None
+    return tuple([int(x) for x in txt.split('.')])
+
+
+def path_ancestors_before_descendants_sort_key(volume: str) -> Tuple[str]:
+    """Chunk up a file path so that parent/ancestor paths sort before
+    children/descendant paths.
+
+    >>> path_ancestors_before_descendants_sort_key('/usr/local/bin')
+    ('usr', 'local', 'bin')
+
+    >>> paths = ['/usr/local', '/usr/local/bin', '/usr']
+    >>> sorted(paths, key=lambda x: path_ancestors_before_descendants_sort_key(x))
+    ['/usr', '/usr/local', '/usr/local/bin']
+
+    """
+    return tuple([x for x in volume.split('/') if len(x) > 0])
+
+
 if __name__ == '__main__':
     import doctest
     doctest.testmod()