diff --git a/files/global.css b/files/global.css index 8cb9ff6..17d714b 100644 --- a/files/global.css +++ b/files/global.css @@ -176,6 +176,7 @@ figure { .tooltip .tagdropdown { padding: 0; + margin: 0; } .tooltip:hover .tooltiptext { @@ -196,6 +197,11 @@ figure { padding: 0; } +.tooltip .tooltiptext ol { + margin-left: 0; + padding-left: 0.5em; +} + .tooltip .tooltiptext .tagentry label { cursor: pointer; width: 100%; diff --git a/modules/generate_html.py b/modules/generate_html.py index 5a20487..12bdc81 100644 --- a/modules/generate_html.py +++ b/modules/generate_html.py @@ -5,6 +5,7 @@ import fnmatch import json from typing import Any from datetime import datetime +from collections import defaultdict from tqdm.auto import tqdm from PIL import Image, ExifTags, TiffImagePlugin, UnidentifiedImageError @@ -189,27 +190,66 @@ def get_image_info(item: str, folder: str) -> dict[str, Any]: tags = xmpdata["xmpmeta"]["RDF"]["Description"]["subject"]["Bag"]["li"] if isinstance(tags, str): tags = [tags] - xmp = xmpdata except TypeError: - ... + pass except KeyError: - ... + pass try: tags = xmpdata["xapmeta"]["RDF"]["Description"]["subject"]["Bag"]["li"] if isinstance(tags, str): tags = [tags] - xmp = xmpdata except TypeError: - ... + pass except KeyError: - ... + pass + try: + tags = xmpdata["xmpmeta"]["RDF"]["Description"]["hierarchicalSubject"]["Bag"]["li"] + if isinstance(tags, str): + tags = [tags] + except TypeError: + pass + except KeyError: + pass + try: + tags = xmpdata["xapmeta"]["RDF"]["Description"]["hierarchicalSubject"]["Bag"]["li"] + if isinstance(tags, str): + tags = [tags] + except TypeError: + pass + except KeyError: + pass if None in tags: tags.remove(None) - if "st" in tags: - tags.remove("st") return {"width": width, "height": height, "tags": tags, "exifdata": exifdata, "xmp": xmp} +def nested_dict(): + return defaultdict(nested_dict) + + +def insert_path(d, path): + for part in path[:-1]: + d = d[part] + last = path[-1] + if not isinstance(d[last], dict): + d[last] = {} + + +def finalize(d): + if isinstance(d, defaultdict): + # Sort keys before recursion + return {k: finalize(d[k]) for k in sorted(d)} + return d or [] + + +def parse_hierarchical_tags(tags, delimiter="|"): + tree = nested_dict() + for tag in tags: + parts = tag.split(delimiter) + insert_path(tree, parts) + return finalize(tree) + + def get_tags(sidecarfile: str) -> list[str]: """ Extracts Tags from XMP sidecar file @@ -230,21 +270,35 @@ def get_tags(sidecarfile: str) -> list[str]: if isinstance(tags, str): tags = [tags] except TypeError: - ... + pass except KeyError: - ... + pass try: tags = xmpdata["xapmeta"]["RDF"]["Description"]["subject"]["Bag"]["li"] if isinstance(tags, str): tags = [tags] except TypeError: - ... + pass except KeyError: - ... + pass + try: + tags = xmpdata["xmpmeta"]["RDF"]["Description"]["hierarchicalSubject"]["Bag"]["li"] + if isinstance(tags, str): + tags = [tags] + except TypeError: + pass + except KeyError: + pass + try: + tags = xmpdata["xapmeta"]["RDF"]["Description"]["hierarchicalSubject"]["Bag"]["li"] + if isinstance(tags, str): + tags = [tags] + except TypeError: + pass + except KeyError: + pass if None in tags: tags.remove(None) - if "st" in tags: - tags.remove("st") return tags @@ -489,9 +543,9 @@ def create_html_file(folder: str, title: str, foldername: str, images: list[dict alltags = set() for img in images: - for tag in img["tags"]: - alltags.add(tag) - alltags = sorted(alltags) + alltags.update(img["tags"]) + + nested_tags = parse_hierarchical_tags(alltags) folder_info = info.get(urllib.parse.quote(folder), "").split("\n") _info = [i for i in folder_info if len(i) > 1] if folder_info else None @@ -541,7 +595,7 @@ def create_html_file(folder: str, title: str, foldername: str, images: list[dict version=version, logo=logo, licensefile=license_url, - tags=alltags, + tags=nested_tags, ) with open(html_file, "w", encoding="utf-8") as f: diff --git a/templates/default.css b/templates/default.css index 5f650be..4e238d1 100644 --- a/templates/default.css +++ b/templates/default.css @@ -52,7 +52,7 @@ background-color: var(--color2); } -.tagentry:hover { +.tagentry > label:hover { background-color: var(--color4); } diff --git a/templates/index.html.j2 b/templates/index.html.j2 index e3ea461..d4f2346 100644 --- a/templates/index.html.j2 +++ b/templates/index.html.j2 @@ -1,3 +1,17 @@ +{%- macro render_tags(tag_tree, parent) -%} +
    + {%- for key, value in tag_tree.items() %} +
  1. + + {%- if value %} + {{ render_tags(value, parent + '|' + key) }} + {%- endif %} +
  2. + {%- endfor %} +
+{%- endmacro -%} @@ -49,15 +63,14 @@
  • {{ header }}