MCPcopy Create free account
hub / github.com/PrairieLearn/PrairieLearn / uploadInstanceQuestionScores

Function uploadInstanceQuestionScores

lib/score-upload.js:26–146  ·  view source on GitHub ↗

* Update question instance scores from a CSV file. * * @param {number} assessment_id - The assessment to update. * @param {csvFile} csvFile - An object with keys {originalname, size, buffer}. * @param {number} user_id - The current user performing the update. * @param {numbe

(assessment_id, csvFile, user_id, authn_user_id, callback)

Source from the content-addressed store, hash-verified

24 * @param {function} callback - A callback(err, job_sequence_id) function.
25 */
26 uploadInstanceQuestionScores(assessment_id, csvFile, user_id, authn_user_id, callback) {
27 debug('uploadInstanceQuestionScores()');
28 if (csvFile == null) {
29 return callback(new Error('No CSV file uploaded'));
30 }
31 const params = {assessment_id};
32 sqldb.queryOneRow(sql.select_assessment_info, params, function(err, result) {
33 if (ERR(err, callback)) return;
34 const assessment_label = result.rows[0].assessment_label;
35 const course_instance_id = result.rows[0].course_instance_id;
36 const course_id = result.rows[0].course_id;
37
38 const options = {
39 course_id: course_id,
40 course_instance_id: course_instance_id,
41 assessment_id: assessment_id,
42 user_id: user_id,
43 authn_user_id: authn_user_id,
44 type: 'upload_instance_question_scores',
45 description: 'Upload question scores for ' + assessment_label,
46 };
47 serverJobs.createJobSequence(options, function(err, job_sequence_id) {
48 if (ERR(err, callback)) return;
49 callback(null, job_sequence_id);
50
51 // We've now triggered the callback to our caller, but we
52 // continue executing below to launch the jobs themselves.
53
54 const jobOptions = {
55 course_id: course_id,
56 course_instance_id: course_instance_id,
57 assessment_id: assessment_id,
58 user_id: user_id,
59 authn_user_id: authn_user_id,
60 type: 'upload_instance_question_scores',
61 description: 'Upload question scores for ' + assessment_label,
62 job_sequence_id: job_sequence_id,
63 last_in_sequence: true,
64 };
65 serverJobs.createJob(jobOptions, function(err, job) {
66 if (err) {
67 logger.error('Error in createJob()', err);
68 serverJobs.failJobSequence(job_sequence_id);
69 return;
70 }
71 job.verbose('Uploading question scores for ' + assessment_label);
72
73 // acculumate output lines in the "output" variable and actually
74 // output put them in blocks, to avoid spamming the updates
75 let output = null;
76 let outputCount = 0;
77 let outputThreshold = 100;
78
79 job.verbose(`Parsing uploaded CSV file "${csvFile.originalname}" (${csvFile.size} bytes)`);
80 job.verbose(`----------------------------------------`);
81 const csvStream = streamifier.createReadStream(csvFile.buffer, {encoding: 'utf8'});
82 const csvConverter = csvtojson({
83 colParser:{

Callers

nothing calls this directly

Calls 3

debugFunction · 0.85
callbackFunction · 0.85
resolveFunction · 0.85

Tested by

no test coverage detected