diff --git a/repo_autoindex/_impl/base.py b/repo_autoindex/_impl/base.py index 55a8121..26b67c6 100644 --- a/repo_autoindex/_impl/base.py +++ b/repo_autoindex/_impl/base.py @@ -56,6 +56,23 @@ class IndexEntry: padding: str = "" icon: str = ICON_OTHER + @property + def sort_key(self): + # Returns a suggested sort key for displaying entries in + # a UI. + + priority = 0 + + # Folders should come first + if self.href.endswith("/"): + priority -= 1 + # And special folders like ".." even earlier + if self.href.startswith("."): + priority -= 1 + + # Entries sort by the priority we calculated, and then by name + return (priority, self.href) + class Repo(ABC): def __init__( diff --git a/repo_autoindex/_impl/tree.py b/repo_autoindex/_impl/tree.py index 168bda4..3fa466b 100644 --- a/repo_autoindex/_impl/tree.py +++ b/repo_autoindex/_impl/tree.py @@ -70,4 +70,6 @@ def treeify( ] ) + out.entries.sort(key=lambda entry: entry.sort_key) + return out diff --git a/tests/test_kickstart_render_typical.py b/tests/test_kickstart_render_typical.py index 6dcac1c..851fdf3 100644 --- a/tests/test_kickstart_render_typical.py +++ b/tests/test_kickstart_render_typical.py @@ -1,4 +1,5 @@ import io +import re from typing import BinaryIO, Optional import textwrap @@ -619,6 +620,30 @@ async def test_typical_index(): assert '' in by_relative_dir["images/pxeboot"].content + # Sample the order of entries in some of the listings. + # Directories are expected to come first. + links = re.findall(r'