#!/usr/bin/env python3 """ Modify announcement banner for development preview deployment. This script modifies the Quarto announcement banner in HTML files to: 1. Make it non-dismissible 2. Add a prominent "DEVELOPMENT PREVIEW" banner at the top 3. Style it with appropriate warning colors Used by the deploy-preview GitHub Actions workflow. """ import os import sys import re from pathlib import Path from typing import List import argparse from datetime import datetime from zoneinfo import ZoneInfo def find_html_files_with_announcement(directory: Path) -> List[Path]: """Find all HTML files that contain quarto-announcement.""" html_files = [] for html_file in directory.rglob("*.html"): try: with open(html_file, 'r', encoding='utf-8') as f: content = f.read() if 'quarto-announcement' in content: html_files.append(html_file) except Exception as e: print(f"⚠️ Warning: Could not read {html_file}: {e}") return html_files def modify_announcement_banner(file_path: Path, commit_hash: str = None, commit_short: str = None) -> bool: """ Modify the announcement banner in an HTML file for development preview. Returns True if modifications were made, False otherwise. """ try: # Read the file with open(file_path, 'r', encoding='utf-8') as f: content = f.read() original_content = content # 1. Make announcement non-dismissible by hiding the close button content = re.sub( r']*>.*?', '', content, flags=re.DOTALL ) # 2. Remove dismissible functionality content = re.sub(r'data-bs-dismiss="alert"', '', content) # 3. Add development preview text at the beginning of the existing content # Get current Eastern Time (EST/EDT) try: # Use timezone-aware datetime with Eastern Time eastern = ZoneInfo("America/New_York") eastern_now = datetime.now(eastern) timestamp = eastern_now.strftime("%Y-%m-%d %H:%M %Z") except Exception: # Fallback to UTC if timezone fails utc_now = datetime.utcnow() timestamp = utc_now.strftime("%Y-%m-%d %H:%M UTC") commit_info = "" if commit_hash and commit_short: commit_info = f''' Built from dev@{commit_short} • {timestamp}''' elif commit_short: commit_info = f''' Built from commit {commit_short} • {timestamp}''' else: commit_info = f''' • {timestamp}''' dev_text = f'''

🚧 DEVELOPMENT PREVIEW - Built from dev@{commit_short or "unknown"} • {timestamp} • Stable version →

''' # Insert the dev text right after the opening of quarto-announcement-content content = re.sub( r'(
\s*)', f'\\1{dev_text}\n', content ) # 4. Keep the original alert-primary styling - don't change it # The dev preview box has its own styling, so we leave the main announcement unchanged # Check if any changes were made if content != original_content: # Write the modified content back with open(file_path, 'w', encoding='utf-8') as f: f.write(content) return True return False except Exception as e: print(f"❌ Error modifying {file_path}: {e}") return False def main(): """Main function to process HTML files.""" parser = argparse.ArgumentParser(description='Modify announcement banners for development preview') parser.add_argument('directory', help='Directory containing HTML files to process') parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose output') parser.add_argument('--commit-hash', help='Full commit hash for the build') parser.add_argument('--commit-short', help='Short commit hash for display') args = parser.parse_args() directory = Path(args.directory) if not directory.exists(): print(f"❌ Error: Directory {directory} does not exist") sys.exit(1) print("🔧 Modifying announcement banners for development preview...") # Find HTML files with announcements html_files = find_html_files_with_announcement(directory) if not html_files: print("ℹ️ No HTML files with announcements found") return print(f"📝 Found {len(html_files)} HTML files with announcements") modified_count = 0 for html_file in html_files: if args.verbose: print(f" 📄 Processing: {html_file.relative_to(directory)}") if modify_announcement_banner(html_file, args.commit_hash, args.commit_short): modified_count += 1 if args.verbose: print(f" ✅ Modified: {html_file.relative_to(directory)}") elif args.verbose: print(f" ⏭️ No changes needed: {html_file.relative_to(directory)}") print(f"✅ Successfully modified {modified_count} files") if modified_count > 0: print("🎨 Development preview banner added to announcement sections") if __name__ == "__main__": main()