Last active
February 11, 2024 17:34
-
-
Save glowinthedark/45e0237920a497e4ff4476892438d562 to your computer and use it in GitHub Desktop.
Script to generate a static HTML image gallery file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Generate a static gallery.html file with all media files below the given folder | |
# for the VERSION WITH THUMBNAIL GENERATION use instead: | |
# https://gist.github.com/glowinthedark/81bc7c250ed245cb7a58d8d6b1f1a63e | |
from datetime import datetime | |
from pathlib import Path | |
from sys import argv | |
from urllib.parse import quote | |
OUTPUT_FILE_NAME = "gallery.html" | |
IMAGE_EXTENSIONS = (".jpg", ".jpeg", ".png", ".svg", ".bmp", ".webp", ".gif", ".heic") | |
VIDEO_EXTENSIONS = (".mp4", ".mkv", ".webm", ".3gp", ".3gpp", ".mov", ".mkv", ".ogv", ".mpg", ".mpeg") | |
AUDIO_EXTENSIONS = (".mp3", ".ogg", ".wav") | |
ASSET_EXTENSIONS = IMAGE_EXTENSIONS + VIDEO_EXTENSIONS + AUDIO_EXTENSIONS | |
def get_creation_date(file_stat): | |
try: | |
return file_stat.st_birthtime | |
except AttributeError: | |
return file_stat.st_mtime | |
def collect_media_assets(root_dir): | |
assets = [] | |
for asset_path in root_dir.rglob("*"): | |
if asset_path.is_file() and asset_path.suffix.lower() in ASSET_EXTENSIONS: | |
size_in_kb = asset_path.stat().st_size // 1024 | |
created_date = datetime.fromtimestamp(get_creation_date(asset_path.stat())).strftime("%Y-%m-%d %H:%M:%S") | |
relative_path = str(asset_path.relative_to(root_dir)) | |
escaped_path = quote(relative_path) | |
if asset_path.suffix.lower() in IMAGE_EXTENSIONS: | |
assets.append(f"""<a class="item" href="{escaped_path}" target="_blank" title="{relative_path} size: {size_in_kb} KB; created: {created_date}"> | |
<img src="{escaped_path}" loading="lazy"> | |
</a>""") | |
elif asset_path.suffix.lower() in VIDEO_EXTENSIONS: | |
assets.append(f"""<a class="item" href="{escaped_path}" target="_blank" title="{relative_path} size: {size_in_kb} KB; created: {created_date}"> | |
<video preload="none" controls><source src="{escaped_path}"></video>{asset_path.name} | |
</a>""") | |
elif asset_path.suffix.lower() in AUDIO_EXTENSIONS: | |
assets.append(f"""<a class="item" href="{escaped_path}" target="_blank" title="{relative_path} size: {size_in_kb} KB; created: {created_date}"> | |
<audio controls src="{escaped_path}"></audio>{asset_path.name} | |
</a>""") | |
print(f'{asset_path}') | |
return assets | |
def generate_gallery_html(html_content, output_file_path: Path): | |
with output_file_path.open(mode="w", encoding="utf-8") as fout: | |
fout.write('''<html> | |
<head> | |
<style> | |
* { | |
font-family: system-ui, sans-serif; | |
} | |
body>div { | |
display: grid; | |
grid-template-columns: repeat(auto-fill, minmax(321px, 1fr)); | |
gap: 5px; | |
} | |
.item { | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
} | |
img, video {max-width: 321px; | |
height: auto; | |
display: table-cell; | |
} | |
a { | |
text-decoration: none; | |
font-size: 14px; | |
} | |
a:hover { | |
color: #0095e4; | |
} | |
a:visited { | |
color: #800080; | |
} | |
a:visited:hover { | |
color: #b900b9; | |
} | |
</style> | |
</head> | |
<body> | |
<div>''' | |
+ html_content | |
+ '''</div> | |
</body> | |
</html>''') | |
print(f"Gallery HTML file generated: {output_file_path.absolute()}") | |
if __name__ == "__main__": | |
root_dir = len(argv) > 1 and argv[1] or '.' # Use 1st arg OR current directory as root | |
base_dir = Path(root_dir).absolute() | |
asset_list = collect_media_assets(base_dir) | |
if not asset_list: | |
print("No media files found.") | |
else: | |
generate_gallery_html('\n'.join(asset_list), base_dir / OUTPUT_FILE_NAME) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment