import subprocess import shutil from pathlib import Path from jinja2 import Environment, FileSystemLoader from config import Config CONFIG = Config.from_yaml("config.yaml") env = Environment(loader=FileSystemLoader(".")) template = env.get_template("template.html") def convert_pdf_to_png(pdf_path: Path): png_path = pdf_path.with_suffix(".png") # Check if PNG exists and is newer than PDF (with 30 second buffer) if png_path.exists(): pdf_mtime = pdf_path.stat().st_mtime png_mtime = png_path.stat().st_mtime if png_mtime >= (pdf_mtime + 30): # 30 second buffer # PNG is up to date, no need to convert return else: print(f"PDF {pdf_path.name} is newer than PNG, reconverting...") print(f"Converting {pdf_path} → {png_path}") subprocess.run([ "convert", "-density", str(CONFIG.png_dpi), str(pdf_path), "-quality", "95", str(png_path) ], check=True) def needs_update(source_file: Path, target_file: Path) -> bool: """Check if target file needs to be updated based on source file modification time""" if not target_file.exists(): return True source_mtime = source_file.stat().st_mtime target_mtime = target_file.stat().st_mtime # Return True if source is newer than target (with 30 second buffer) return source_mtime > (target_mtime + 30) def build_gallery(source_dir: Path, web_dir: Path, relative_path: Path = None): """ Build gallery for a directory, copying files to web directory and generating index.html Args: source_dir: Source directory containing PDFs web_dir: Target web directory relative_path: Relative path for navigation (None for root) """ if relative_path is None: relative_path = Path(".") # Ensure web directory exists target_dir = web_dir / relative_path target_dir.mkdir(parents=True, exist_ok=True) # Find all PDFs in source directory pdfs = sorted(source_dir.glob("*.pdf")) items = [] for pdf in pdfs: # Convert PDF to PNG in source directory convert_pdf_to_png(pdf) png_path = pdf.with_suffix(".png") # Copy both PDF and PNG to target directory only if needed target_pdf = target_dir / pdf.name target_png = target_dir / png_path.name if needs_update(pdf, target_pdf): print(f"Copying {pdf.name} to {target_pdf}") shutil.copy2(pdf, target_pdf) else: print(f"Skipping {pdf.name} (up to date)") if png_path.exists() and needs_update(png_path, target_png): print(f"Copying {png_path.name} to {target_png}") shutil.copy2(png_path, target_png) elif png_path.exists(): print(f"Skipping {png_path.name} (up to date)") items.append({ "name": pdf.name, "pdf_href": pdf.name, "png_href": png_path.name }) # Find subdirectories in source subdirs = sorted([d.name for d in source_dir.iterdir() if d.is_dir()]) # Generate index.html in target directory output_html = target_dir / "index.html" # Create a meaningful title if str(relative_path) == ".": title = "Gallery" else: title = f"Gallery: {relative_path}" with output_html.open("w") as f: f.write(template.render( title=title, items=items, subdirs=subdirs, relpath=str(relative_path) )) print(f"Generated {output_html}") # Recursively process subdirectories for subdir in subdirs: source_subdir = source_dir / subdir new_relative_path = relative_path / subdir build_gallery(source_subdir, web_dir, new_relative_path) def loop_over_sources(): web_root = Path(CONFIG.web_folder) for source in CONFIG.sources: print(f"Processing {source.name}: {source.path}") if source.path.is_dir(): # Create a subdirectory based on plot_root and source name source_web_dir = web_root / CONFIG.plot_root / source.name build_gallery(source.path, source_web_dir) print(f"Processed {source.name}: {source.path}") elif source.path.suffix == ".pdf": # For single PDF files, copy to web root with plot_root and source name as directory source_web_dir = web_root / CONFIG.plot_root / source.name convert_pdf_to_png(source.path) png_path = source.path.with_suffix(".png") # Ensure web directory exists source_web_dir.mkdir(parents=True, exist_ok=True) # Copy PDF and PNG to web directory only if needed target_pdf = source_web_dir / source.path.name target_png = source_web_dir / png_path.name if needs_update(source.path, target_pdf): print(f"Copying {source.path.name} to {target_pdf}") shutil.copy2(source.path, target_pdf) else: print(f"Skipping {source.path.name} (up to date)") if png_path.exists() and needs_update(png_path, target_png): print(f"Copying {png_path.name} to {target_png}") shutil.copy2(png_path, target_png) elif png_path.exists(): print(f"Skipping {png_path.name} (up to date)") # Create items list for template items = [{ "name": source.path.name, "pdf_href": source.path.name, "png_href": png_path.name }] # Generate index.html for single PDF 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 )) print(f"Generated {output_html}") print(f"Processed {source.name}: {source.path}") if __name__ == "__main__": loop_over_sources() print("Done")