001package edu.pdx.cs410J.grader.canvas;
002
003import edu.pdx.cs410J.ParserException;
004import edu.pdx.cs410J.grader.gradebook.*;
005import org.slf4j.Logger;
006import org.slf4j.LoggerFactory;
007
008import java.io.File;
009import java.io.FileReader;
010import java.io.IOException;
011import java.io.PrintStream;
012import java.util.List;
013import java.util.Optional;
014
015public class GradesFromCanvasImporter {
016
017  private static final Logger logger = LoggerFactory.getLogger("edu.pdx.cs410J.grader");
018
019  public static void importGradesFromCanvas(GradesFromCanvas canvasGrades, GradeBook gradebook) {
020    List<GradesFromCanvas.CanvasStudent> students = canvasGrades.getStudents();
021    logger.debug("Importing grades for " + students.size() + " students");
022
023    for (GradesFromCanvas.CanvasStudent canvasStudent : students) {
024      Optional<Student> student = canvasGrades.findStudentInGradebookForCanvasStudent(canvasStudent, gradebook);
025      if (student.isEmpty()) {
026        String message = "Could not find student " + canvasStudent + " in gradebook";
027        System.err.println(message);
028
029      } else {
030        for (GradesFromCanvas.CanvasAssignment canvasAssignment : canvasStudent.getAssignments()) {
031          Optional<Assignment> optional = canvasGrades.findAssignmentInGradebookForCanvasQuiz(canvasAssignment, gradebook);
032          Assignment assignment = optional.orElseThrow(() -> new IllegalStateException("No assignment named \"" + canvasAssignment.getName() + "\" in gradebook"));
033
034          Double score = canvasStudent.getScore(canvasAssignment);
035          logger.debug("Recording grade of " + score + " for " + student.get() + " for " + assignment.getName());
036          student.get().setGrade(assignment.getName(), new Grade(assignment, score));
037        }
038      }
039    }
040  }
041
042  public static void main(String[] args) throws IOException, ParserException {
043    String canvasCsvFileName = null;
044    String gradeBookFileName = null;
045
046    for (String arg : args) {
047      if (canvasCsvFileName == null) {
048        canvasCsvFileName = arg;
049
050      } else if (gradeBookFileName == null) {
051        gradeBookFileName = arg;
052
053      } else {
054        usage("Extraneous command line argument: " + arg);
055      }
056    }
057
058    if (canvasCsvFileName == null) {
059      usage("Missing Canvas CSV file name");
060    }
061
062    if (gradeBookFileName == null) {
063      usage("Missing grade book file name");
064    }
065
066    GradesFromCanvas canvasGrades = parseCanvasCsvFile(canvasCsvFileName);
067    GradeBook gradebook = parseGradeBook(gradeBookFileName);
068    importGradesFromCanvas(canvasGrades, gradebook);
069
070    saveGradeBookIfModified(gradebook, gradeBookFileName);
071  }
072
073  private static void saveGradeBookIfModified(GradeBook gradeBook, String gradeBookFileName) {
074    if (gradeBook.isDirty()) {
075      File file = new File(gradeBookFileName);
076      try {
077        XmlDumper dumper = new XmlDumper(file);
078        dumper.dump(gradeBook);
079
080      } catch (IOException e) {
081        usage("Can't write grade book in \"" + gradeBookFileName + "\"");
082      }
083    }
084  }
085
086  private static GradeBook parseGradeBook(String gradeBookFileName) throws IOException, ParserException {
087    File gradeBookFile = new File(gradeBookFileName);
088    if (!gradeBookFile.exists()) {
089      usage("Grade Book file \"" + gradeBookFile + "\" does not exist");
090    }
091
092    XmlGradeBookParser parser = new XmlGradeBookParser(gradeBookFile);
093    return parser.parse();
094  }
095
096  private static GradesFromCanvas parseCanvasCsvFile(String canvasCsvFileName) throws IOException {
097    File canvasCsvFile = new File(canvasCsvFileName);
098    if (!canvasCsvFile.exists()) {
099      usage("Canvas CSV file \"" + canvasCsvFile + "\" does not exist");
100    }
101
102    CanvasGradesCSVParser parser = new CanvasGradesCSVParser(new FileReader(canvasCsvFile));
103    return parser.getGrades();
104  }
105
106  private static void usage(String message) {
107    PrintStream err = System.err;
108
109    err.println("+++ " + message);
110    err.println();
111    err.println("usage: java GradesFromCanvasImporter canvasGradesCsvFileName gradeBookFileName");
112    err.println("    canvasGradesCsvFileName       Name of the CSV grades file exported from Canvas");
113    err.println("    gradeBookFileName             Gradebook file");
114    err.println();
115    err.println("Imports grades from Canvas into a gradebook");
116    err.println();
117
118    System.exit(1);
119  }
120}