mirror of
https://github.com/release-engineering/repo-autoindex.git
synced 2025-02-23 13:42:52 +00:00

Directories are generally expected to be listed first in directory indexes. That was already working for yum and file repos, but wasn't the case for kickstart repos due to their combination of different types of content. This commit applies a consistent sorting so that directories will always come first, and entries will otherwise be sorted by name, for all repo types.
75 lines
2.2 KiB
Python
75 lines
2.2 KiB
Python
from dataclasses import dataclass, field, replace
|
|
from collections.abc import Iterable
|
|
|
|
from .base import ICON_FOLDER, IndexEntry
|
|
|
|
|
|
@dataclass
|
|
class TreeNode:
|
|
entries: list[IndexEntry] = field(default_factory=list)
|
|
children: list["TreeNode"] = field(default_factory=list)
|
|
relative_dir: str = ""
|
|
|
|
|
|
def treeify(
|
|
all_entries: Iterable[IndexEntry],
|
|
relative_dir: str = "",
|
|
index_href_suffix: str = "",
|
|
) -> TreeNode:
|
|
out = TreeNode(relative_dir=relative_dir)
|
|
|
|
if relative_dir:
|
|
out.entries.append(
|
|
IndexEntry(
|
|
icon=ICON_FOLDER,
|
|
href=f"../{index_href_suffix}",
|
|
text="parent directory",
|
|
)
|
|
)
|
|
|
|
entries_by_leading_dir: dict[str, list[IndexEntry]] = {}
|
|
for entry in all_entries:
|
|
subdir = entry.href.removeprefix(relative_dir + "/")
|
|
components = subdir.split("/", 1)
|
|
if len(components) == 1:
|
|
# file is in this dir
|
|
subdir = ""
|
|
else:
|
|
subdir = components[0]
|
|
entries_by_leading_dir.setdefault(subdir, []).append(entry)
|
|
|
|
for key in sorted(entries_by_leading_dir.keys()):
|
|
if key:
|
|
out.entries.append(
|
|
IndexEntry(
|
|
icon=ICON_FOLDER,
|
|
href=f"{key}/{index_href_suffix}",
|
|
text=f"{key}/",
|
|
# TODO: in theory we could look up the latest time and sum
|
|
# the sizes here.
|
|
time=" ",
|
|
size=" ",
|
|
)
|
|
)
|
|
sub_entries = entries_by_leading_dir[key]
|
|
subdir = key
|
|
if relative_dir:
|
|
subdir = f"{relative_dir}/{subdir}"
|
|
out.children.append(
|
|
treeify(
|
|
sub_entries,
|
|
relative_dir=subdir,
|
|
index_href_suffix=index_href_suffix,
|
|
)
|
|
)
|
|
else:
|
|
out.entries.extend(
|
|
[
|
|
replace(e, href=e.href.removeprefix(relative_dir + "/"))
|
|
for e in entries_by_leading_dir[key]
|
|
]
|
|
)
|
|
|
|
out.entries.sort(key=lambda entry: entry.sort_key)
|
|
|
|
return out
|