#!/usr/bin/env python3
"""
Pre-sushi: Update sushi-config.yaml with DAK API page and menu entries.
This script runs BEFORE sushi compilation to ensure the DAK API page
is registered in sushi-config.yaml so sushi includes it in the build.
The resource scanning and placeholder generation happens in post-sushi
after fsh-generated/ is created.
Usage:
python 2-update_sushi_config.py [ig_root_dir]
"""
import yaml
import sys
import os
import json
from pathlib import Path
def create_dak_api_md_if_needed(ig_root: Path) -> bool:
"""Create dak-api.md file with proper content if it doesn't exist."""
dak_api_path = ig_root / 'input' / 'pagecontent' / 'dak-api.md'
# Check if the file already exists with proper content
if dak_api_path.exists():
try:
content = dak_api_path.read_text(encoding='utf-8')
# Check for either the old comment marker or the new div placeholder
if 'id="dak-api-content-placeholder"' in content or '' in content:
print(f"dak-api.md already exists with proper content")
return True
else:
print(f"dak-api.md exists but missing placeholder, updating...")
except Exception as e:
print(f"Error reading existing dak-api.md: {e}")
else:
print(f"dak-api.md does not exist, creating...")
# Create the directories if they don't exist
try:
dak_api_path.parent.mkdir(parents=True, exist_ok=True)
except Exception as e:
print(f"Failed to create directory structure: {e}")
return False
# Create the dak-api.md content with a div placeholder that survives HTML conversion
dak_api_content = """
This page provides access to Data Access Kit (DAK) API documentation and schemas.
{: .no_toc .text-delta }
1. TOC
{:toc}
"""
try:
dak_api_path.write_text(dak_api_content, encoding='utf-8')
print(f"Successfully created dak-api.md with placeholder div")
return True
except Exception as e:
print(f"Error creating dak-api.md: {e}")
return False
def page_exists_in_config(pages: dict, page_name: str) -> bool:
"""Recursively check if a page exists anywhere in the pages structure."""
if pages is None:
return False
for key, value in pages.items():
if key == page_name:
return True
# Check nested pages (value is a dict with nested structure)
if isinstance(value, dict):
if page_exists_in_config(value, page_name):
return True
return False
def check_smart_base_dependency(config: dict) -> bool:
"""Check if this repository should have DAK API configured."""
# Check if this is the smart-base repository
repo_id = config.get('id', '')
if repo_id == 'smart.who.int.base':
print(f"This is the smart-base repository (id: {repo_id})")
return True
# Check if smart-base is listed as a dependency
dependencies = config.get('dependencies', {})
smart_base_patterns = [
'smart-base',
'smart.who.int.base',
'who.smart.base',
'smart.base'
]
for dep_name in dependencies.keys():
for pattern in smart_base_patterns:
if pattern in dep_name.lower():
print(f"Found smart-base dependency: {dep_name}")
return True
return False
def update_sushi_config(ig_root: Path) -> bool:
"""Update sushi-config.yaml with DAK API page and menu entries."""
sushi_config_path = ig_root / 'sushi-config.yaml'
config_updated = False
try:
with open(sushi_config_path, 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
print(f"Successfully loaded {sushi_config_path}")
# Check if this repo should have DAK API
if not check_smart_base_dependency(config):
print("This is not the smart-base repository and smart-base is not listed as a dependency.")
print("Skipping DAK API configuration.")
return False
# Create dak-api.md if needed
if not create_dak_api_md_if_needed(ig_root):
print("Failed to create dak-api.md, but continuing with sushi-config processing...")
# Ensure pages section exists
if 'pages' not in config:
config['pages'] = {}
# Check if dak-api.md is registered anywhere in pages (supports nested structure)
if not page_exists_in_config(config.get('pages'), 'dak-api.md'):
# Add at root level of pages
config['pages']['dak-api.md'] = {'title': 'DAK API Documentation Hub'}
config_updated = True
print("Added dak-api.md to pages section")
else:
print("dak-api.md already exists in pages section")
# Ensure menu section exists
if 'menu' not in config:
config['menu'] = {}
# Check if DAK API link already exists anywhere in the menu
def menu_item_exists(menu: dict, target_url: str) -> bool:
"""Check if a menu item with the given URL exists anywhere in the menu."""
if menu is None:
return False
for key, value in menu.items():
if value == target_url:
return True
if isinstance(value, dict):
if menu_item_exists(value, target_url):
return True
return False
if not menu_item_exists(config.get('menu'), 'dak-api.html'):
# Ensure Indices subsection exists under menu
if 'Indices' not in config['menu']:
config['menu']['Indices'] = {}
# Add DAK API to Indices
config['menu']['Indices']['DAK API'] = 'dak-api.html'
config_updated = True
print("Added DAK API to menu Indices section")
else:
print("DAK API already exists in menu")
# Write back the updated config if changes were made
if config_updated:
with open(sushi_config_path, 'w', encoding='utf-8') as f:
yaml.dump(config, f, default_flow_style=False, sort_keys=False, allow_unicode=True)
print("sushi-config.yaml updated successfully")
return True
else:
print("sushi-config.yaml already contains required DAK API entries")
return False
except FileNotFoundError:
print(f"Error: {sushi_config_path} not found")
return False
except Exception as e:
print(f"Error updating sushi-config.yaml: {e}")
return False
def main():
"""Main entry point."""
# First argument is the IG root directory (from template execution)
if len(sys.argv) > 1:
ig_root = Path(sys.argv[1])
else:
ig_root = Path(".")
print(f"IG root directory: {ig_root.absolute()}")
# Update sushi config
update_sushi_config(ig_root)
# Always exit successfully - this is a non-critical step
sys.exit(0)
if __name__ == "__main__":
main()