haikal/tours/management/commands/generate_tours.py
2025-06-13 01:58:40 +03:00

85 lines
3.3 KiB
Python

from django.core.management.base import BaseCommand
import yaml
import os
import json
from django.conf import settings
class Command(BaseCommand):
help = "Generate IntroJS tour definitions from workflow documentation"
def handle(self, *args, **kwargs):
input_file = "haikal_kb.yaml"
output_dir = os.path.join(settings.BASE_DIR, 'static', 'js', 'tours')
# Create output directory if it doesn't exist
os.makedirs(output_dir, exist_ok=True)
try:
with open(input_file, 'r', encoding='utf-8') as f:
kb = yaml.safe_load(f)
except Exception as e:
self.stdout.write(self.style.ERROR(f"Error reading knowledge base file: {e}"))
return
workflows = kb.get("user_workflows", {})
tours_created = 0
# Map of common UI elements to their likely selectors
element_selectors = {
"inventory": "#inventory-menu, .inventory-nav, nav .inventory",
"add car": "#add-car-button, .btn-add-car, button:contains('Add Car')",
"save": "button[type='submit'], .btn-save, #save-button",
"cancel": ".btn-cancel, #cancel-button, button:contains('Cancel')",
"vin": "#vin-input, input[name='vin'], .vin-field",
"make": "#make-select, select[name='make'], .make-field",
"model": "#model-select, select[name='model'], .model-field",
"series": "#series-select, select[name='series'], .series-field",
"trim": "#trim-select, select[name='trim'], .trim-field",
"price": "#price-input, input[name='price'], .price-field",
"color": "#color-select, select[name='color'], .color-field",
"invoice": "#invoice-section, .invoice-tab, #create-invoice",
"customer": "#customer-select, select[name='customer'], .customer-field",
"finance": "#finance-menu, .finance-nav, nav .finance",
}
for workflow_name, workflow in workflows.items():
steps = workflow.get("steps", [])
if not steps:
continue
tour_steps = []
for i, step in enumerate(steps):
# Try to identify UI element from step description
element = None
for key, selector in element_selectors.items():
if key.lower() in step.lower():
element = selector
break
tour_step = {
"title": f"Step {i + 1}",
"intro": step,
"position": "bottom"
}
if element:
tour_step["element"] = element
tour_steps.append(tour_step)
# Save the tour definition as JSON
tour_filename = workflow_name.lower().replace(' ', '_') + '_tour.json'
with open(os.path.join(output_dir, tour_filename), 'w', encoding='utf-8') as f:
json.dump({
"name": workflow_name,
"description": workflow.get("description", ""),
"steps": tour_steps
}, f, indent=2)
tours_created += 1
self.stdout.write(self.style.SUCCESS(f"✅ Created {tours_created} IntroJS tour definitions in {output_dir}"))