diff --git a/scripts/training/generate_certificates.py b/scripts/training/generate_certificates.py new file mode 100644 index 00000000..85e4d756 --- /dev/null +++ b/scripts/training/generate_certificates.py @@ -0,0 +1,331 @@ +#!/usr/bin/env python3 +""" +Certificate and Badge Generator for AITBC Training + +Generates: +1. Markdown badges (shields.io style) for completed stages +2. HTML certificates with proper formatting +3. Summary certificate for completing all stages +""" + +import json +import os +import sys +from datetime import datetime, timezone +from pathlib import Path + +CERT_DIR = Path(__file__).parent / ".training_state" / "certificates" +BADGE_DIR = Path(__file__).parent / ".training_state" / "badges" +HTML_DIR = Path(__file__).parent / ".training_state" / "html_certificates" + + +def ensure_dirs(): + """Ensure output directories exist.""" + BADGE_DIR.mkdir(parents=True, exist_ok=True) + HTML_DIR.mkdir(parents=True, exist_ok=True) + + +def load_certificate(stage_num: int) -> dict: + """Load certificate JSON for a stage.""" + cert_file = CERT_DIR / f"stage{stage_num}_certificate.json" + if not cert_file.exists(): + return None + with open(cert_file) as f: + return json.load(f) + + +def generate_markdown_badge(stage_num: int, cert_data: dict) -> str: + """Generate shields.io markdown badge for a stage.""" + badge_label = f"Stage {stage_num}" + badge_message = "Completed" + badge_color = "brightgreen" + + # URL encode spaces + badge_url = f"https://img.shields.io/badge/{badge_label.replace(' ', '%20')}-{badge_message.replace(' ', '%20')}-{badge_color}?style=flat-square" + markdown = f"[![Stage {stage_num}]({badge_url})]({CERT_DIR}/stage{stage_num}_certificate.json)" + return markdown + + +def generate_html_certificate(stage_num: int, cert_data: dict) -> str: + """Generate HTML certificate for a stage.""" + stage_name = cert_data.get("stage_name", f"Stage {stage_num}") + timestamp = cert_data.get("completion_timestamp", datetime.now(timezone.utc).isoformat()) + wallet = cert_data.get("wallet_name", "Unknown") + cert_id = cert_data.get("certificate_id", "Unknown") + + html = f""" + + + Certificate - Stage {stage_num} + + + +
+
🏆 Certificate of Completion
+
AITBC Agent Training Program
+ +
Stage {stage_num}: {stage_name}
+ +
+
+ Certificate ID: {cert_id} +
+
+ Completed: {timestamp} +
+
+ Wallet: {wallet} +
+
+ Training Program: hermes AITBC Mastery Training +
+
+ +
+ ✓ Stage Completed + ✓ Hands-On Training + ✓ Blockchain Verified +
+ + +
+ +""" + return html + + +def generate_summary_certificate(completed_stages: list) -> str: + """Generate summary HTML certificate for completing all stages.""" + stages_html = "" + for stage in sorted(completed_stages): + cert = load_certificate(stage) + stage_name = cert.get("stage_name", f"Stage {stage}") if cert else f"Stage {stage}" + stages_html += f'
Stage {stage}: {stage_name}
\n' + + html = f""" + + + Mastery Certificate - AITBC Training + + + +
+
🎓 Mastery Certificate
+
AITBC Agent Training Program
+ +
+ Congratulations! You have completed all {len(completed_stages)} training stages +
+ +
+{stages_html} +
+ + +
+ +""" + return html + + +def generate_markdown_summary(completed_stages: list) -> str: + """Generate Markdown summary with all badges.""" + markdown = "# AITBC Training Certificates\n\n" + markdown += f"Completed {len(completed_stages)} / 11 stages\n\n" + + markdown += "## Badges\n\n" + for stage in sorted(completed_stages): + cert = load_certificate(stage) + if cert: + badge = generate_markdown_badge(stage, cert) + markdown += f"{badge} " + + markdown += "\n\n## Stages Completed\n\n" + for stage in sorted(completed_stages): + cert = load_certificate(stage) + if cert: + stage_name = cert.get("stage_name", f"Stage {stage}") + timestamp = cert.get("completion_timestamp", "Unknown") + markdown += f"- **Stage {stage}: {stage_name}** - Completed {timestamp}\n" + + return markdown + + +def main(): + """Main function.""" + ensure_dirs() + + # Find all completed stages + completed_stages = [] + for i in range(11): # Stages 0-10 + cert = load_certificate(i) + if cert: + completed_stages.append(i) + + # Generate markdown badge + badge_md = generate_markdown_badge(i, cert) + badge_file = BADGE_DIR / f"stage{i}_badge.md" + with open(badge_file, 'w') as f: + f.write(badge_md) + + # Generate HTML certificate + html = generate_html_certificate(i, cert) + html_file = HTML_DIR / f"stage{i}_certificate.html" + with open(html_file, 'w') as f: + f.write(html) + + print(f"✓ Generated badge and HTML certificate for Stage {i}") + + # Generate summary certificate if all stages completed + if len(completed_stages) == 11: + summary_html = generate_summary_certificate(completed_stages) + summary_file = HTML_DIR / "mastery_certificate.html" + with open(summary_file, 'w') as f: + f.write(summary_html) + print(f"✓ Generated Mastery Certificate: {summary_file}") + + # Generate Markdown summary + if completed_stages: + md_summary = generate_markdown_summary(completed_stages) + summary_md_file = BADGE_DIR / "training_summary.md" + with open(summary_md_file, 'w') as f: + f.write(md_summary) + print(f"✓ Generated Markdown summary: {summary_md_file}") + + print(f"\nTotal completed stages: {len(completed_stages)} / 11") + print(f"Badges directory: {BADGE_DIR}") + print(f"HTML certificates: {HTML_DIR}") + + +if __name__ == "__main__": + main() diff --git a/scripts/training/master_training_launcher.sh b/scripts/training/master_training_launcher.sh index 4bffd7d2..b7701aa9 100755 --- a/scripts/training/master_training_launcher.sh +++ b/scripts/training/master_training_launcher.sh @@ -34,6 +34,8 @@ START_TIME=$(date +%s) PROGRESS_FILE="$SCRIPT_DIR/.training_progress" STATE_DIR="$SCRIPT_DIR/.training_state" CERT_DIR="$STATE_DIR/certificates" +BADGE_DIR="$STATE_DIR/badges" +HTML_CERT_DIR="$STATE_DIR/html_certificates" # Skill update flag (default: disabled) ENABLE_SKILL_UPDATE="${ENABLE_SKILL_UPDATE:-false}" @@ -397,16 +399,16 @@ capture_learnings() { # View certificates view_certificates() { print_header "Stage Completion Certificates" - - # Ensure CERT_DIR exists + + # Ensure directories exist if [ ! -d "$CERT_DIR" ]; then mkdir -p "$CERT_DIR" fi - + # Collect certificate files into array local cert_files=() local cert_count=0 - + if [ -d "$CERT_DIR" ]; then for cert_file in "$CERT_DIR"/stage*_certificate.json; do if [ -f "$cert_file" ]; then @@ -415,42 +417,81 @@ view_certificates() { fi done fi - + if [ $cert_count -eq 0 ]; then print_warning "No certificates found yet" echo "Complete stages to earn certificates" return 0 fi - + echo -e "${BOLD}📜 Certificates Earned:${NC}" echo - + # Display certificates with index for i in "${!cert_files[@]}"; do local cert_file="${cert_files[$i]}" - local stage_num=$(echo "$cert_file" | grep -o 'stage[0-10]' | grep -o '[0-10]') + local stage_num=$(echo "$cert_file" | grep -o 'stage[0-9]*' | grep -o '[0-9]*') local stage_name=$(get_stage_name $stage_num) local timestamp=$(python3 -c "import json; print(json.load(open('$cert_file'))['completion_timestamp'])" 2>/dev/null || echo "Unknown") - + echo -e " ${GREEN}$(($i+1))${NC}. Stage $stage_num: $stage_name" echo " Completed: $timestamp" echo " File: $cert_file" + + # Show badge path if exists + local badge_file="$BADGE_DIR/stage${stage_num}_badge.md" + if [ -f "$badge_file" ]; then + echo " Badge: $badge_file" + fi + + # Show HTML cert path if exists + local html_file="$HTML_CERT_DIR/stage${stage_num}_certificate.html" + if [ -f "$html_file" ]; then + echo " HTML: $html_file" + fi + echo done - + echo -e "${BOLD}Total certificates: $cert_count${NC}" - + + # Show badges summary if available + if [ -d "$BADGE_DIR" ] && [ -f "$BADGE_DIR/training_summary.md" ]; then + echo + echo -e "${BOLD}🏅 Badges Summary:${NC}" + cat "$BADGE_DIR/training_summary.md" + fi + echo echo -n "View certificate details? Enter number [1-$cert_count] or N: " read -r view_choice - - if [[ "$view_choice" =~ ^[0-10]+$ ]] && [ "$view_choice" -ge 1 ] && [ "$view_choice" -le "$cert_count" ]; then + + if [[ "$view_choice" =~ ^[0-9]+$ ]] && [ "$view_choice" -ge 1 ] && [ "$view_choice" -le "$cert_count" ]; then local idx=$(($view_choice - 1)) local cert_file="${cert_files[$idx]}" if [ -f "$cert_file" ]; then echo echo -e "${BOLD}Certificate Details:${NC}" cat "$cert_file" | python3 -m json.tool 2>/dev/null || cat "$cert_file" + + # Offer to open HTML certificate + local stage_num=$(echo "$cert_file" | grep -o 'stage[0-9]*' | grep -o '[0-9]*') + local html_file="$HTML_CERT_DIR/stage${stage_num}_certificate.html" + if [ -f "$html_file" ]; then + echo + echo -n "Open HTML certificate in browser? [y/N]: " + read -r open_choice + if [[ "$open_choice" =~ ^[Yy]$ ]]; then + if command -v xdg-open &> /dev/null; then + xdg-open "$html_file" &> /dev/null & + elif command -v python3 &> /dev/null; then + echo "Starting HTTP server for certificates..." + cd "$HTML_CERT_DIR" && python3 -m http.server 8888 & + echo "View certificates at: http://localhost:8888" + echo "Press Ctrl+C to stop the server when done" + fi + fi + fi fi fi }