* Update assessment 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 {num
(assessment_id, csvFile, user_id, authn_user_id, callback)
| 155 | * @param {function} callback - A callback(err, job_sequence_id) function. |
| 156 | */ |
| 157 | uploadAssessmentInstanceScores(assessment_id, csvFile, user_id, authn_user_id, callback) { |
| 158 | debug('uploadAssessmentInstanceScores()'); |
| 159 | if (csvFile == null) { |
| 160 | return callback(new Error('No CSV file uploaded')); |
| 161 | } |
| 162 | const params = {assessment_id}; |
| 163 | sqldb.queryOneRow(sql.select_assessment_info, params, function(err, result) { |
| 164 | if (ERR(err, callback)) return; |
| 165 | const assessment_label = result.rows[0].assessment_label; |
| 166 | const course_instance_id = result.rows[0].course_instance_id; |
| 167 | const course_id = result.rows[0].course_id; |
| 168 | |
| 169 | const options = { |
| 170 | course_id: course_id, |
| 171 | course_instance_id: course_instance_id, |
| 172 | assessment_id: assessment_id, |
| 173 | user_id: user_id, |
| 174 | authn_user_id: authn_user_id, |
| 175 | type: 'upload_assessment_instance_scores', |
| 176 | description: 'Upload total scores for ' + assessment_label, |
| 177 | }; |
| 178 | serverJobs.createJobSequence(options, function(err, job_sequence_id) { |
| 179 | if (ERR(err, callback)) return; |
| 180 | callback(null, job_sequence_id); |
| 181 | |
| 182 | // We've now triggered the callback to our caller, but we |
| 183 | // continue executing below to launch the jobs themselves. |
| 184 | |
| 185 | const jobOptions = { |
| 186 | course_id: course_id, |
| 187 | course_instance_id: course_instance_id, |
| 188 | assessment_id: assessment_id, |
| 189 | user_id: user_id, |
| 190 | authn_user_id: authn_user_id, |
| 191 | type: 'upload_assessment_instance_scores', |
| 192 | description: 'Upload total scores for ' + assessment_label, |
| 193 | job_sequence_id: job_sequence_id, |
| 194 | last_in_sequence: true, |
| 195 | }; |
| 196 | serverJobs.createJob(jobOptions, function(err, job) { |
| 197 | if (err) { |
| 198 | logger.error('Error in createJob()', err); |
| 199 | serverJobs.failJobSequence(job_sequence_id); |
| 200 | return; |
| 201 | } |
| 202 | job.verbose('Uploading total scores for ' + assessment_label); |
| 203 | |
| 204 | // acculumate output lines in the "output" variable and actually |
| 205 | // output put them in blocks, to avoid spamming the updates |
| 206 | let output = null; |
| 207 | let outputCount = 0; |
| 208 | let outputThreshold = 100; |
| 209 | |
| 210 | job.verbose(`Parsing uploaded CSV file "${csvFile.originalname}" (${csvFile.size} bytes)`); |
| 211 | job.verbose(`----------------------------------------`); |
| 212 | const csvStream = streamifier.createReadStream(csvFile.buffer, {encoding: 'utf8'}); |
| 213 | const csvConverter = csvtojson({ |
| 214 | colParser:{ |