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:
 | 
			
		||||
        """
 | 
			
		||||
        Sort entries by IP address, keeping default entries on top.
 | 
			
		||||
        Sort entries by IP address, keeping default entries on top in fixed order.
 | 
			
		||||
        
 | 
			
		||||
        Args:
 | 
			
		||||
            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:
 | 
			
		||||
                ip_str = entry.ip_address.lstrip('# ')
 | 
			
		||||
                ip_obj = ipaddress.ip_address(ip_str)
 | 
			
		||||
                # Default entries always come first (priority 0), others get priority 1
 | 
			
		||||
                priority = 0 if entry.is_default_entry() else 1
 | 
			
		||||
                # Create a tuple for sorting: (priority, version, ip_int)
 | 
			
		||||
                return (priority, ip_obj.version, int(ip_obj))
 | 
			
		||||
                # Create a tuple for sorting: (version, ip_int)
 | 
			
		||||
                return (ip_obj.version, int(ip_obj))
 | 
			
		||||
            except ValueError:
 | 
			
		||||
                # If IP parsing fails, use string comparison with high sort priority
 | 
			
		||||
                priority = 0 if entry.is_default_entry() else 1
 | 
			
		||||
                return (priority, 999, entry.ip_address)
 | 
			
		||||
                # If IP parsing fails, use string comparison
 | 
			
		||||
                return (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:
 | 
			
		||||
        """
 | 
			
		||||
        Sort entries by first hostname, keeping default entries on top.
 | 
			
		||||
        Sort entries by first hostname, keeping default entries on top in fixed order.
 | 
			
		||||
        
 | 
			
		||||
        Args:
 | 
			
		||||
            ascending: Sort in ascending order if True, descending if False
 | 
			
		||||
        """
 | 
			
		||||
        def sort_key(entry):
 | 
			
		||||
            # Default entries always come first (priority 0), others get priority 1
 | 
			
		||||
            priority = 0 if entry.is_default_entry() else 1
 | 
			
		||||
            hostname = (entry.hostnames[0] if entry.hostnames else "").lower()
 | 
			
		||||
            return (priority, hostname)
 | 
			
		||||
        # 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()]
 | 
			
		||||
        
 | 
			
		||||
        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]:
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue