|
20 | 20 | # ] |
21 | 21 | # /// |
22 | 22 |
|
| 23 | +import json |
23 | 24 | import subprocess |
24 | 25 | from typing import List, Union |
25 | 26 | from pathlib import Path |
@@ -167,6 +168,7 @@ def _export(folder: Path, output_dir: Path, as_app: bool=False) -> List[dict]: |
167 | 168 | { |
168 | 169 | "display_name": (nb.stem.replace("_", " ").title()), |
169 | 170 | "html_path": str(nb.with_suffix(".html")), |
| 171 | + "type": "app" if as_app else "notebook" |
170 | 172 | } |
171 | 173 | for nb in notebooks |
172 | 174 | if _export_html_wasm(nb, output_dir, as_app=as_app) |
@@ -207,18 +209,81 @@ def main( |
207 | 209 | logger.info(f"Using template file: {template_file}") |
208 | 210 |
|
209 | 211 | # Export notebooks from the notebooks/ directory |
210 | | - notebooks_data = _export(Path("notebooks"), output_dir, as_app=False) |
| 212 | + notebooks_raw = _export(Path("notebooks"), output_dir, as_app=False) |
211 | 213 |
|
212 | 214 | # Export apps from the apps/ directory |
213 | | - apps_data = _export(Path("apps"), output_dir, as_app=True) |
| 215 | + apps_raw = _export(Path("apps"), output_dir, as_app=True) |
| 216 | + |
| 217 | + # Merge notebooks and apps into a single dataset |
| 218 | + merged_data = {} |
| 219 | + |
| 220 | + # Process notebooks |
| 221 | + for nb in notebooks_raw: |
| 222 | + stem = Path(nb["html_path"]).stem |
| 223 | + merged_data[stem] = { |
| 224 | + "title": nb["display_name"], |
| 225 | + "source_link": nb["html_path"], |
| 226 | + "type": "notebook" |
| 227 | + } |
| 228 | + |
| 229 | + # Process apps and merge with notebooks |
| 230 | + for app in apps_raw: |
| 231 | + stem = Path(app["html_path"]).stem |
| 232 | + if stem in merged_data: |
| 233 | + merged_data[stem]["app_link"] = app["html_path"] |
| 234 | + else: |
| 235 | + merged_data[stem] = { |
| 236 | + "title": app["display_name"], |
| 237 | + "app_link": app["html_path"], |
| 238 | + "type": "app" |
| 239 | + } |
| 240 | + |
| 241 | + final_data = list(merged_data.values()) |
| 242 | + |
| 243 | + # Load metadata from cards.json and merge it in |
| 244 | + try: |
| 245 | + cards_json_path = Path("templates/cards.json") |
| 246 | + if cards_json_path.exists(): |
| 247 | + with open(cards_json_path, "r", encoding="utf-8") as f: |
| 248 | + cards_metadata = json.load(f) |
| 249 | + |
| 250 | + # Create a lookup for metadata by title or link |
| 251 | + meta_lookup = {} |
| 252 | + for meta in cards_metadata: |
| 253 | + # Try to match by source_link filename |
| 254 | + if "source_link" in meta: |
| 255 | + m_stem = Path(meta["source_link"]).stem |
| 256 | + meta_lookup[m_stem] = meta |
| 257 | + |
| 258 | + # Update final_data with values from cards.json |
| 259 | + for item in final_data: |
| 260 | + # We need the stem to look up in meta_lookup |
| 261 | + # The link could be notebooks/name.html or apps/name.html |
| 262 | + link = item.get("source_link") or item.get("app_link") |
| 263 | + if link: |
| 264 | + stem = Path(link).stem |
| 265 | + if stem in meta_lookup: |
| 266 | + m = meta_lookup[stem] |
| 267 | + item.update({ |
| 268 | + "title": m.get("title", item["title"]), |
| 269 | + "description": m.get("description", ""), |
| 270 | + "tags": m.get("tags", []), |
| 271 | + "date": m.get("date", ""), |
| 272 | + "image_url": m.get("image_url", ""), |
| 273 | + "app_link": m.get("app_link", item.get("app_link")), |
| 274 | + "source_link": m.get("source_link", item.get("source_link")) |
| 275 | + }) |
| 276 | + logger.info("Successfully merged metadata from cards.json") |
| 277 | + except Exception as e: |
| 278 | + logger.error(f"Failed to load or merge cards.json: {e}") |
214 | 279 |
|
215 | 280 | # Exit if no notebooks or apps were found |
216 | | - if not notebooks_data and not apps_data: |
| 281 | + if not final_data: |
217 | 282 | logger.warning("No notebooks or apps found!") |
218 | 283 | return |
219 | 284 |
|
220 | 285 | # Generate the index.html file that lists all notebooks and apps |
221 | | - _generate_index(output_dir=output_dir, notebooks_data=notebooks_data, apps_data=apps_data, template_file=template_file) |
| 286 | + _generate_index(output_dir=output_dir, notebooks_data=final_data, apps_data=[], template_file=template_file) |
222 | 287 |
|
223 | 288 | logger.info(f"Build completed successfully. Output directory: {output_dir}") |
224 | 289 |
|
|
0 commit comments