6 Commits

Author SHA1 Message Date
00b5020642 single tag fix 2025-06-22 20:49:20 +02:00
492ea8755f ... 2025-06-22 20:00:52 +02:00
39da474db6 i am an idiot 2025-06-22 19:33:40 +02:00
44bcd5607f added xapmeta 2025-06-22 18:00:36 +02:00
5ff44a1912 fixed nonexisitng xmp metadata error 2025-06-22 17:53:46 +02:00
4241f3965a added tag redout from xmp subject 2025-06-22 17:50:04 +02:00
6 changed files with 27 additions and 7 deletions

View File

@@ -1 +1 @@
2.7.0 2.7.1

View File

@@ -97,7 +97,7 @@ To generate a web manifest file:
- The script generates the preview thumbnails in a `.thumbnails` subdirectory within the root folder. - The script generates the preview thumbnails in a `.thumbnails` subdirectory within the root folder.
- The `.lock` file prevents multiple instances of the script from running simultaneously. Make sure to remove it if the script terminates unexpectedly. - The `.lock` file prevents multiple instances of the script from running simultaneously. Make sure to remove it if the script terminates unexpectedly.
- Add a `info` file into any directory containing pictures and it will be read and displayed as a tooltip on the website. - Add a `info` file into any directory containing pictures and it will be read and displayed as a tooltip on the website.
- Add tags to the Image exif or to `.metadata.json` to tag images for filtering. - Add tags to the Image xmp `subject` or to `.metadata.json` to tag images for filtering.
## License ## License

View File

@@ -100,12 +100,14 @@ def get_image_info(item: str, folder: str) -> dict[str, Any]:
try: try:
with Image.open(file) as img: with Image.open(file) as img:
logger.info("extracting image information", extra={"file": file}) logger.info("extracting image information", extra={"file": file})
exif = img.getexif()
width, height = img.size width, height = img.size
exif = img.getexif()
xmpdata = img.getxmp()
except UnidentifiedImageError: except UnidentifiedImageError:
logger.error("cannot identify image file", extra={"file": file}) logger.error("cannot identify image file", extra={"file": file})
print(f"cannot identify image file: {file}") print(f"cannot identify image file: {file}")
return {"width": None, "height": None, "tags": None, "exifdata": None} return {"width": None, "height": None, "tags": None, "exifdata": None, "xmp": None}
if exif: if exif:
logger.info("extracting EXIF data", extra={"file": file}) logger.info("extracting EXIF data", extra={"file": file})
ifd = exif.get_ifd(ExifTags.IFD.Exif) ifd = exif.get_ifd(ExifTags.IFD.Exif)
@@ -141,9 +143,26 @@ def get_image_info(item: str, folder: str) -> dict[str, Any]:
for key in ["PrintImageMatching", "UserComment", "MakerNote"]: for key in ["PrintImageMatching", "UserComment", "MakerNote"]:
if key in exifdata: if key in exifdata:
del exifdata[key] del exifdata[key]
return {"width": width, "height": height, "tags": [], "exifdata": exifdata}
else: else:
return {"width": width, "height": height, "tags": [], "exifdata": None} exifdata = None
tags = []
xmp = None
if xmpdata:
if xmpdata.get("xmpmeta", False):
if isinstance(xmpdata["xmpmeta"]["RDF"]["Description"], dict):
if xmpdata["xmpmeta"]["RDF"]["Description"].get("subject", False):
tags = xmpdata["xmpmeta"]["RDF"]["Description"]["subject"]["Bag"]["li"]
if isinstance(tags, str):
tags = [tags]
xmp = xmpdata
if xmpdata.get("xapmeta", False):
if isinstance(xmpdata["xapmeta"]["RDF"]["Description"], dict):
if xmpdata["xapmeta"]["RDF"]["Description"].get("subject", False):
tags = xmpdata["xapmeta"]["RDF"]["Description"]["subject"]["Bag"]["li"]
if isinstance(tags, str):
tags = [tags]
xmp = xmpdata
return {"width": width, "height": height, "tags": tags, "exifdata": exifdata, "xmp": xmp}
def process_image(item: str, folder: str, _args: Args, baseurl: str, metadata: dict[str, dict[str, int]], raw: list[str]) -> dict[str, Any]: def process_image(item: str, folder: str, _args: Args, baseurl: str, metadata: dict[str, dict[str, int]], raw: list[str]) -> dict[str, Any]:
@@ -173,6 +192,7 @@ def process_image(item: str, folder: str, _args: Args, baseurl: str, metadata: d
"height": metadata[item]["height"], "height": metadata[item]["height"],
"tags": metadata[item]["tags"], "tags": metadata[item]["tags"],
"exifdata": metadata[item].get("exifdata", ""), "exifdata": metadata[item].get("exifdata", ""),
"xmp": metadata[item].get("xmp", ""),
} }
path = os.path.join(_args.root_directory, ".thumbnails", baseurl, item + ".jpg") path = os.path.join(_args.root_directory, ".thumbnails", baseurl, item + ".jpg")
if not os.path.exists(path) or _args.regenerate_thumbnails: if not os.path.exists(path) or _args.regenerate_thumbnails:

BIN
test/example/DSC00009.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 MiB

BIN
test/example/DSC01106.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

View File

@@ -460,7 +460,7 @@ Creative Commons may be contacted at creativecommons.org.</br>
<img src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" alt="" /> <img src="https://mirrors.creativecommons.org/presskit/icons/nc.svg" alt="" />
<img src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="" /> <img src="https://mirrors.creativecommons.org/presskit/icons/sa.svg" alt="" />
</a> </a>
<span class="attribution">Made with <a href="https://github.com/greflm13/StaticGalleryBuilder" target="_blank" rel="noopener noreferrer">StaticGalleryBuilder 2.7.0</a> by <a <span class="attribution">Made with <a href="https://github.com/greflm13/StaticGalleryBuilder" target="_blank" rel="noopener noreferrer">StaticGalleryBuilder 2.7.1</a> by <a
href="https://github.com/greflm13" target="_blank" rel="noopener noreferrer"><svg width="48.858002mm" height="21.24mm" viewBox="0 0 48.858002 21.24" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <text xml:space="preserve" x="21.124891" y="17.106812" font-style="normal" font-variant="normal" font-weight="300" font-stretch="condensed" font-size="2.46944px" line-height="9.33327px" font-family="Barlow Condensed Light" fill="#6e6e6e" stroke-width="1" fill-opacity="1">sorogon</text> <text xml:space="preserve" x="2.3734004" y="14.853325" font-style="normal" font-variant="normal" font-weight="250" font-stretch="condensed" font-size="16.9333px" line-height="63.9997px" font-family="Barlow Condensed Thin" fill="#6e6e6e" stroke-width="1" fill-opacity="1">&lt;/srgn&gt;</text> </svg></a>.</span> href="https://github.com/greflm13" target="_blank" rel="noopener noreferrer"><svg width="48.858002mm" height="21.24mm" viewBox="0 0 48.858002 21.24" version="1.1" id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <text xml:space="preserve" x="21.124891" y="17.106812" font-style="normal" font-variant="normal" font-weight="300" font-stretch="condensed" font-size="2.46944px" line-height="9.33327px" font-family="Barlow Condensed Light" fill="#6e6e6e" stroke-width="1" fill-opacity="1">sorogon</text> <text xml:space="preserve" x="2.3734004" y="14.853325" font-style="normal" font-variant="normal" font-weight="250" font-stretch="condensed" font-size="16.9333px" line-height="63.9997px" font-family="Barlow Condensed Thin" fill="#6e6e6e" stroke-width="1" fill-opacity="1">&lt;/srgn&gt;</text> </svg></a>.</span>
<button onclick="topFunction()" id="totop" title="Back to Top">Back to Top</button> <button onclick="topFunction()" id="totop" title="Back to Top">Back to Top</button>
</div> </div>