From 491a4a9fd2cbbf2205bac94c9c6412d225bc43d6 Mon Sep 17 00:00:00 2001 From: Kylian Schmidt Date: Mon, 21 Jul 2025 15:54:17 +0200 Subject: [PATCH] Add gallery index.html to website --- generate_gallery.py | 163 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 2 deletions(-) diff --git a/generate_gallery.py b/generate_gallery.py index 0217a0f..ea93ba1 100644 --- a/generate_gallery.py +++ b/generate_gallery.py @@ -115,12 +115,15 @@ def build_gallery(source_dir: Path, web_dir: Path, current_metadata = merge_metadata(inherited_metadata, folder_metadata) pdf_files = list(source_dir.glob("*.pdf")) + png_files = list(source_dir.glob("*.png")) subdirs = [d for d in source_dir.iterdir() if d.is_dir()] items = [] plot_metadata_cache = {} + processed_stems = set() + # First, process PDF files (with PNG conversion) for pdf_file in pdf_files: png_file = pdf_file.with_suffix(".png") @@ -148,7 +151,8 @@ def build_gallery(source_dir: Path, web_dir: Path, plot_metadata = {} for k, v in plot_metadata.items(): if isinstance(v, str): - plot_metadata[k] = v.replace('<', '').replace('>', '').replace('&', '').replace('"', "'") + plot_metadata[k] = (v.replace('<', '').replace('>', '') + .replace('&', '').replace('"', "'")) plot_metadata_cache[pdf_file.stem] = plot_metadata items.append({ @@ -157,6 +161,40 @@ def build_gallery(source_dir: Path, web_dir: Path, "png_href": png_file.name, "metadata": plot_metadata }) + processed_stems.add(pdf_file.stem) + + # Second, process standalone PNG files (no corresponding PDF) + for png_file in png_files: + # Skip if we already processed this PNG via its PDF + if png_file.stem in processed_stems: + continue + + web_png = web_dir / png_file.name + + if needs_update(png_file, web_png): + print(f"Copying {png_file} to {web_png}") + shutil.copy2(png_file, web_png) + else: + print(f"Skipping {png_file.name} (up to date)") + + # Resolve metadata for this standalone PNG plot + plot_metadata = resolve_metadata_for_plot(png_file, current_metadata) + if not plot_metadata: + plot_metadata = {} + for k, v in plot_metadata.items(): + if isinstance(v, str): + plot_metadata[k] = (v.replace('<', '').replace('>', '') + .replace('&', '').replace('"', "'")) + plot_metadata_cache[png_file.stem] = plot_metadata + + # For standalone PNGs, link to the PNG for both thumbnail and main view + items.append({ + "name": png_file.stem, + "pdf_href": png_file.name, # Link to PNG instead of PDF + "png_href": png_file.name, # Thumbnail is also the PNG + "metadata": plot_metadata + }) + processed_stems.add(png_file.stem) # Save metadata cache for this directory save_metadata_cache(web_dir, plot_metadata_cache) @@ -271,6 +309,64 @@ def format_file_size(size_bytes: int) -> str: return f"{size:.1f} {size_names[i]}" +def generate_root_index(gallery_root: Path) -> None: + """ + Generate the main index.html file for the gallery root. + + This serves as the entry point to navigate to all configured sources. + + Args: + gallery_root: Path to the gallery root directory + """ + # Collect information about all source directories + subdirs = [] + total_plots = 0 + total_size = 0 + + for source in CONFIG.sources: + source_web_dir = gallery_root / source.name + if source_web_dir.exists(): + subdirs.append(source.name) + + # Count plots and calculate size for this source + stats = calculate_directory_stats(source_web_dir) + total_plots += stats.get("file_count", 0) + total_size += stats.get("total_size", 0) + + # Calculate overall statistics + stats = { + "file_count": total_plots, + "folder_count": len(subdirs), + "total_size": format_file_size(total_size), + "total_size_bytes": total_size + } + + # Assets are at the same level as gallery for root + assets_path = "../assets" + + output_html = gallery_root / "index.html" + with output_html.open("w") as f: + rendered_html = template.render( + title="Scientific Gallery", + items=[], # No individual plots at root level + subdirs=subdirs, + relpath=".", + paths=CONFIG.paths, + ui=CONFIG.ui, + stats=stats, + folder_metadata={ + "description": ("Main gallery containing scientific plots " + "and analyses"), + "sources": [{"name": s.name, "path": s.path} + for s in CONFIG.sources] + }, + assets_path=assets_path + ) + f.write(rendered_html) + + print(f"Generated root gallery index: {output_html}") + + def main(clean_first: bool = False) -> None: """ Main entry point for gallery generation. @@ -382,6 +478,65 @@ def main(clean_first: bool = False) -> None: print(f"Generated {output_html}") print(f"Processed {source.name}: {source.path}") + elif source_path.is_file() and source_path.suffix == '.png': + # Handle standalone PNG files + source_web_dir = gallery_root / source.name + source_web_dir.mkdir(parents=True, exist_ok=True) + + png_name = source_path.name + web_png_path = source_web_dir / png_name + + if needs_update(source_path, web_png_path): + print(f"Copying {source_path} to {web_png_path}") + shutil.copy2(source_path, web_png_path) + else: + print(f"Skipping {source_path.name} (up to date)") + + # Resolve metadata for this single PNG plot + plot_metadata = resolve_metadata_for_plot(source_path, {}) + plot_metadata_cache[source_path.stem] = plot_metadata + + items = [{ + "name": source_path.stem, + "pdf_href": png_name, # Link to PNG instead of PDF + "png_href": png_name, # Thumbnail is the PNG + "metadata": plot_metadata + }] + + # Save metadata cache for this directory + plot_cache = {source_path.stem: plot_metadata} + save_metadata_cache(source_web_dir, plot_cache) + + # Calculate statistics for single file + current_stats = calculate_directory_stats(source_web_dir) + stats = { + "file_count": 1, + "folder_count": 0, + "total_size": format_file_size(current_stats["total_size"]), + "total_size_bytes": current_stats["total_size"] + } + + # Calculate relative path to assets for single file + # Single files are at depth 1 (gallery_root/source.name/index.html) + assets_path = "../assets" + + output_html = source_web_dir / "index.html" + with output_html.open("w") as f: + f.write(template.render( + title=source.name, + items=items, + subdirs=[], + relpath=source.name, + paths=CONFIG.paths, + ui=CONFIG.ui, + stats=stats, + folder_metadata={}, + assets_path=assets_path + )) + + print(f"Generated {output_html}") + print(f"Processed {source.name}: {source.path}") + elif source_path.is_dir(): source_web_dir = gallery_root / source.name source_web_dir.mkdir(parents=True, exist_ok=True) @@ -389,9 +544,13 @@ def main(clean_first: bool = False) -> None: print(f"Processed {source.name}: {source.path}") else: print(f"Warning: Source {source.path} is neither a " - f"directory nor a PDF file") + f"directory nor a PDF/PNG file") print("Done") + + # Generate root index.html for gallery navigation + generate_root_index(gallery_root) + # No copying of this script to CGI location