""" Main entry point: builds a clash-free dummy schedule and renders all five timetable views (batch/department/room/student/teacher -wise) as .xlsx files under result/templates//. Run: python app/template_generator.py """ import os import shutil import sys APP_DIR = os.path.dirname(os.path.abspath(__file__)) ROOT_DIR = os.path.dirname(APP_DIR) sys.path.insert(0, APP_DIR) sys.path.insert(0, os.path.join(ROOT_DIR, "controller")) sys.path.insert(0, os.path.join(ROOT_DIR, "templates", "batch-wise")) sys.path.insert(0, os.path.join(ROOT_DIR, "templates", "department-wise")) sys.path.insert(0, os.path.join(ROOT_DIR, "templates", "room-wise")) sys.path.insert(0, os.path.join(ROOT_DIR, "templates", "student-wise")) sys.path.insert(0, os.path.join(ROOT_DIR, "templates", "teacher-wise")) from template_controller import build_schedule # noqa: E402 from conflict_checker import check_all_conflicts # noqa: E402 from conflict_checker.student_conflict_checker import format_student_conflicts # noqa: E402 from conflict_checker.teacher_conflict_checker import format_teacher_conflicts # noqa: E402 from template_logger import reset_log, log_error, log_info # noqa: E402 from batch_wise_template import generate_batch_wise_templates # noqa: E402 from department_wise_template import generate_department_wise_templates # noqa: E402 from room_wise_template import generate_room_wise_templates # noqa: E402 from student_wise_template import generate_student_wise_templates # noqa: E402 from teacher_wise_template import generate_teacher_wise_templates # noqa: E402 RESULT_DIR = os.path.join(ROOT_DIR, "result", "templates") VIEW_NAMES = ["batch-wise", "department-wise", "room-wise", "student-wise", "teacher-wise"] def clear_result_dir(): """Removes every previous run's output so stale files never linger.""" for view_name in VIEW_NAMES: output_dir = os.path.join(RESULT_DIR, view_name) if os.path.exists(output_dir): shutil.rmtree(output_dir) os.makedirs(output_dir, exist_ok=True) def main(): reset_log() clear_result_dir() data_csv_marker = os.path.join(ROOT_DIR, "data", "dummy", "blocks", "rooms.csv") if not os.path.exists(data_csv_marker): print("Dummy data not found — generating it first...") sys.path.insert(0, os.path.join(ROOT_DIR, "data", "dummy")) from generate_dummy_data import main as generate_dummy_data generate_dummy_data() print() print("Loading data and building clash-free schedule...") data, sessions = build_schedule() print(f"Scheduled {len(sessions)} sessions.\n") log_info("Running conflict checks (student/batch and teacher)...") report = check_all_conflicts(sessions) if report["has_conflicts"]: for line in format_student_conflicts(report["student_conflicts"]): log_error(f"STUDENT CONFLICT: {line}") for line in format_teacher_conflicts(report["teacher_conflicts"]): log_error(f"TEACHER CONFLICT: {line}") log_error( f"Found {len(report['student_conflicts'])} student conflict(s) and " f"{len(report['teacher_conflicts'])} teacher conflict(s)." ) else: log_info("No conflicts found — schedule is clash-free for students and teachers.") generators = [ ("batch-wise", generate_batch_wise_templates), ("department-wise", generate_department_wise_templates), ("room-wise", generate_room_wise_templates), ("student-wise", generate_student_wise_templates), ("teacher-wise", generate_teacher_wise_templates), ] total_files = 0 for view_name, generate_fn in generators: output_dir = os.path.join(RESULT_DIR, view_name) written = generate_fn(sessions, data, output_dir) total_files += len(written) print(f"[{view_name}] generated {len(written)} file(s) -> {output_dir}") print(f"\nDone. {total_files} timetable file(s) written under {RESULT_DIR}") if __name__ == "__main__": main()