Refactor sorting methods in HostsFile to maintain fixed order for default entries while sorting non-default entries by IP and hostname.
This commit is contained in:
parent
3084650c27
commit
3e892daf98
1 changed files with 64 additions and 17 deletions
|
@ -200,40 +200,87 @@ class HostsFile:
|
||||||
|
|
||||||
def sort_by_ip(self, ascending: bool = True) -> None:
|
def sort_by_ip(self, ascending: bool = True) -> None:
|
||||||
"""
|
"""
|
||||||
Sort entries by IP address, keeping default entries on top.
|
Sort entries by IP address, keeping default entries on top in fixed order.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ascending: Sort in ascending order if True, descending if False
|
ascending: Sort in ascending order if True, descending if False
|
||||||
"""
|
"""
|
||||||
def sort_key(entry):
|
# Separate default and non-default entries
|
||||||
|
default_entries = [entry for entry in self.entries if entry.is_default_entry()]
|
||||||
|
non_default_entries = [entry for entry in self.entries if not entry.is_default_entry()]
|
||||||
|
|
||||||
|
def ip_sort_key(entry):
|
||||||
try:
|
try:
|
||||||
ip_str = entry.ip_address.lstrip('# ')
|
ip_str = entry.ip_address.lstrip('# ')
|
||||||
ip_obj = ipaddress.ip_address(ip_str)
|
ip_obj = ipaddress.ip_address(ip_str)
|
||||||
# Default entries always come first (priority 0), others get priority 1
|
# Create a tuple for sorting: (version, ip_int)
|
||||||
priority = 0 if entry.is_default_entry() else 1
|
return (ip_obj.version, int(ip_obj))
|
||||||
# Create a tuple for sorting: (priority, version, ip_int)
|
|
||||||
return (priority, ip_obj.version, int(ip_obj))
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# If IP parsing fails, use string comparison with high sort priority
|
# If IP parsing fails, use string comparison
|
||||||
priority = 0 if entry.is_default_entry() else 1
|
return (999, entry.ip_address)
|
||||||
return (priority, 999, entry.ip_address)
|
|
||||||
|
|
||||||
self.entries.sort(key=sort_key, reverse=not ascending)
|
# Keep default entries in their natural fixed order (don't sort them)
|
||||||
|
# Define the fixed order for default entries
|
||||||
|
default_order = [
|
||||||
|
{"ip": "127.0.0.1", "hostname": "localhost"},
|
||||||
|
{"ip": "255.255.255.255", "hostname": "broadcasthost"},
|
||||||
|
{"ip": "::1", "hostname": "localhost"},
|
||||||
|
]
|
||||||
|
|
||||||
|
# Sort default entries according to their fixed order
|
||||||
|
def default_sort_key(entry):
|
||||||
|
for i, default in enumerate(default_order):
|
||||||
|
if (entry.ip_address == default["ip"] and
|
||||||
|
entry.hostnames and entry.hostnames[0] == default["hostname"]):
|
||||||
|
return i
|
||||||
|
return 999 # fallback for any unexpected default entries
|
||||||
|
|
||||||
|
default_entries.sort(key=default_sort_key)
|
||||||
|
|
||||||
|
# Sort non-default entries according to the specified direction
|
||||||
|
non_default_entries.sort(key=ip_sort_key, reverse=not ascending)
|
||||||
|
|
||||||
|
# Combine: default entries always first, then sorted non-default entries
|
||||||
|
self.entries = default_entries + non_default_entries
|
||||||
|
|
||||||
def sort_by_hostname(self, ascending: bool = True) -> None:
|
def sort_by_hostname(self, ascending: bool = True) -> None:
|
||||||
"""
|
"""
|
||||||
Sort entries by first hostname, keeping default entries on top.
|
Sort entries by first hostname, keeping default entries on top in fixed order.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
ascending: Sort in ascending order if True, descending if False
|
ascending: Sort in ascending order if True, descending if False
|
||||||
"""
|
"""
|
||||||
def sort_key(entry):
|
# Separate default and non-default entries
|
||||||
# Default entries always come first (priority 0), others get priority 1
|
default_entries = [entry for entry in self.entries if entry.is_default_entry()]
|
||||||
priority = 0 if entry.is_default_entry() else 1
|
non_default_entries = [entry for entry in self.entries if not entry.is_default_entry()]
|
||||||
hostname = (entry.hostnames[0] if entry.hostnames else "").lower()
|
|
||||||
return (priority, hostname)
|
|
||||||
|
|
||||||
self.entries.sort(key=sort_key, reverse=not ascending)
|
def hostname_sort_key(entry):
|
||||||
|
hostname = (entry.hostnames[0] if entry.hostnames else "").lower()
|
||||||
|
return hostname
|
||||||
|
|
||||||
|
# Keep default entries in their natural fixed order (don't sort them)
|
||||||
|
# Define the fixed order for default entries
|
||||||
|
default_order = [
|
||||||
|
{"ip": "127.0.0.1", "hostname": "localhost"},
|
||||||
|
{"ip": "255.255.255.255", "hostname": "broadcasthost"},
|
||||||
|
{"ip": "::1", "hostname": "localhost"},
|
||||||
|
]
|
||||||
|
|
||||||
|
# Sort default entries according to their fixed order
|
||||||
|
def default_sort_key(entry):
|
||||||
|
for i, default in enumerate(default_order):
|
||||||
|
if (entry.ip_address == default["ip"] and
|
||||||
|
entry.hostnames and entry.hostnames[0] == default["hostname"]):
|
||||||
|
return i
|
||||||
|
return 999 # fallback for any unexpected default entries
|
||||||
|
|
||||||
|
default_entries.sort(key=default_sort_key)
|
||||||
|
|
||||||
|
# Sort non-default entries according to the specified direction
|
||||||
|
non_default_entries.sort(key=hostname_sort_key, reverse=not ascending)
|
||||||
|
|
||||||
|
# Combine: default entries always first, then sorted non-default entries
|
||||||
|
self.entries = default_entries + non_default_entries
|
||||||
|
|
||||||
def find_entries_by_hostname(self, hostname: str) -> List[int]:
|
def find_entries_by_hostname(self, hostname: str) -> List[int]:
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue