pygacity.util.distribute module

Distribute built exam PDFs to students.

Reads a Blackboard Learn gradebook CSV, assigns exam versions to students round-robin, creates per-student output folders, and optionally emails exams via Outlook COM automation.

pygacity.util.distribute.discover_exams(build_dir: Path) Dict[int, Tuple[Path, Path | None]][source]

Scan build_dir for exam and solution PDFs.

Detects files matching <jobname>-<serial>.pdf and pairs them with <jobname>_soln-<serial>.pdf when present.

Parameters:

build_dir (Path) – Directory containing built exam PDFs.

Returns:

Mapping of serial (int) to (exam_path, soln_path_or_None), sorted by serial number.

Return type:

dict

pygacity.util.distribute.distribute_exams(build_dir: Path | str, gradebook_path: Path | str, output_dir: Path | str = 'distributed', filter_column: str | None = None, email: bool = False, email_suffix: str = '@drexel.edu', subject: str = 'Your exam', body: str = 'Attached is your exam. Please contact your instructor with any questions.', dry_run: bool = False, include_solutions: bool = True) int[source]

Assign exam versions to students round-robin and create per-student output folders. Optionally email exams via Outlook.

Parameters:
  • build_dir (Path or str) – Directory containing built exam PDFs.

  • gradebook_path (Path or str) – Blackboard Learn gradebook CSV.

  • output_dir (Path or str) – Root directory for per-student subfolders.

  • filter_column (str or None) – Column name where "yes"/"true" selects students.

  • email (bool) – If True, send exams via Outlook COM automation.

  • email_suffix (str) – Appended to the Username column to form email addresses.

  • subject (str) – Email subject line.

  • body (str) – Plain-text email body.

  • dry_run (bool) – If True, preview email actions without sending.

  • include_solutions (bool) – If True (default), include solution PDFs in student folders and email attachments. If False, only the exam PDF is distributed.

Returns:

0 on success, 1 on error.

Return type:

int

pygacity.util.distribute.distribute_subcommand(args) int[source]

CLI entry point for the distribute subcommand.

pygacity.util.distribute.read_gradebook(gradebook_path: Path, filter_column: str | None = None) DataFrame[source]

Read a Blackboard Learn gradebook CSV and return a filtered, sorted DataFrame of students.

Parameters:
  • gradebook_path (Path) – Path to the CSV file.

  • filter_column (str or None) – If specified, only include rows where this column’s value is "yes" or "true" (case-insensitive).

Returns:

Sorted by (“Last Name”, “First Name”).

Return type:

pd.DataFrame