commit dedd94746a25e4c912408bc585a67c08855358fd
parent 3bb8334fbc5594fc332e217d6ba03760e8e28e18
Author: Hunter
Date:   Fri, 11 Jul 2025 18:08:13 -0400

add automation to create image-manifest.json

Diffstat:
A.github/workflows/generate-manifest.yml | 44++++++++++++++++++++++++++++++++++++++++++++
Agenerate_image_manifest.py | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aimage-manifest.json | 18++++++++++++++++++
Msw.js | 36++++++++++++++----------------------
4 files changed, 135 insertions(+), 22 deletions(-)

diff --git a/.github/workflows/generate-manifest.yml b/.github/workflows/generate-manifest.yml @@ -0,0 +1,43 @@ +name: Generate Image Manifest + +on: + push: + branches: [ main ] + paths: [ 'images/**' ] # Only run when images are added/changed + workflow_dispatch: # Allow manual trigger + +jobs: + generate-manifest: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + + - name: Generate image manifest + run: python generate_image_manifest.py + + - name: Check for changes + id: verify-changed-files + run: | + if [ -n "$(git status --porcelain)" ]; then + echo "changed=true" >> $GITHUB_OUTPUT + else + echo "changed=false" >> $GITHUB_OUTPUT + fi + + - name: Commit and push changes + if: steps.verify-changed-files.outputs.changed == 'true' + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add image-manifest.json + git commit -m "Auto-update image manifest [skip ci]" + git push +\ No newline at end of file diff --git a/generate_image_manifest.py b/generate_image_manifest.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +""" +Generate image manifest for PWA caching +Scans the images/ directory and creates a JSON manifest file +""" + +import os +import json +from pathlib import Path + +def generate_image_manifest(): + """Generate a JSON manifest of all images in the images/ directory""" + + # Define supported image extensions + image_extensions = {'.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp'} + + # Get the directory where this script is located + script_dir = Path(__file__).parent + images_dir = script_dir / 'images' + + # Check if images directory exists + if not images_dir.exists(): + print(f"Images directory not found: {images_dir}") + return + + # Collect all image files + image_files = [] + + for file_path in images_dir.iterdir(): + if file_path.is_file() and file_path.suffix.lower() in image_extensions: + # Create relative path from web root + relative_path = f"/images/{file_path.name}" + image_files.append(relative_path) + + # Sort for consistent output + image_files.sort() + + # Create manifest object + manifest = { + "images": image_files, + "generated_at": "auto-generated by GitHub Actions", + "total_images": len(image_files) + } + + # Write manifest file + manifest_path = script_dir / 'image-manifest.json' + with open(manifest_path, 'w', encoding='utf-8') as f: + json.dump(manifest, f, indent=2, sort_keys=True) + + print(f"Generated manifest with {len(image_files)} images:") + for img in image_files: + print(f" - {img}") + + return manifest + +if __name__ == "__main__": + manifest = generate_image_manifest() + print(f"\nManifest saved to: image-manifest.json") +\ No newline at end of file diff --git a/image-manifest.json b/image-manifest.json @@ -0,0 +1,17 @@ +{ + "generated_at": "auto-generated by GitHub Actions", + "images": [ + "/images/ceedee.gif", + "/images/floppy.gif", + "/images/mac.png", + "/images/pika_construction.gif", + "/images/pizza.gif", + "/images/rollerskate.png", + "/images/scared_mouse.gif", + "/images/sun.png", + "/images/underconstruction.gif", + "/images/welcome.gif", + "/images/windows.gif" + ], + "total_images": 11 +} +\ No newline at end of file diff --git a/sw.js b/sw.js @@ -1,4 +1,4 @@ -const CACHE_NAME = 'web-workshop-v3'; +const CACHE_NAME = 'web-workshop-v4'; const urlsToCache = [ '/', '/index.html', @@ -44,35 +44,27 @@ async function cacheDirectoryFiles(cache, directories) { } } -// Function to programmatically cache all images +// Function to cache all images using the generated manifest async function cacheImages(cache) { - const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp']; - try { - const response = await fetch('/images/'); + const response = await fetch('/image-manifest.json'); if (response.ok) { - const html = await response.text(); - const imagePattern = new RegExp(`href="([^"]*\\.(${imageExtensions.join('|')}))"`, 'gi'); - const links = html.match(imagePattern); + const manifest = await response.json(); + console.log(`Caching ${manifest.total_images} images from manifest`); - if (links) { - const imageFiles = links.map(link => { - const match = link.match(/href="([^"]*)"/); - return match ? '/images/' + match[1] : null; - }).filter(Boolean); - - for (const imageFile of imageFiles) { - try { - await cache.add(imageFile); - console.log(`Cached image: ${imageFile}`); - } catch (e) { - console.log(`Failed to cache image ${imageFile}:`, e); - } + for (const imagePath of manifest.images) { + try { + await cache.add(imagePath); + console.log(`Cached image: ${imagePath}`); + } catch (e) { + console.log(`Failed to cache image ${imagePath}:`, e); } } + } else { + console.log('No image manifest found, skipping image caching'); } } catch (e) { - console.log('Failed to cache images directory:', e); + console.log('Failed to load image manifest:', e); } }