<commit_before>var ERR = require('async-stacktrace');
var express = require('express');
var router = express.Router();
var AWS = require('aws-sdk');

var config = require('../../lib/config');
var logger = require('../../lib/logger');
var assessments = require('../../assessments');
var sqldb = require('../../lib/sqldb');
var sqlLoader = require('../../lib/sql-loader');
var sql = sqlLoader.loadSqlEquiv(__filename);
var externalGradingSocket = require('../../lib/external-grading-socket');

// FIXME move this to assessments.js for better code reuse; pull the nice
// error-handling logic from messageQueue.js into this function as well
function processResults(data) {
    let gradingResult;
    if (!data.succeeded || !data.results) {
        gradingResult = {
            gradingId: data.job_id,
            grading: {
                startTime: data.start_time || null,
                endTime: data.end_time || null,
                score: 0,
                feedback: data
            }
        }
    } else {
        gradingResult = {
            gradingId: data.job_id,
            grading: {
                startTime: data.start_time || null,
                endTime: data.end_time || null,
                score: data.results.score,
                feedback: data
            }
        }
    }

    assessments.processGradingResult(gradingResult);
}

router.post('/', function(req, res, next) {

    const data = req.body;
    if (data.event === 'grading_start') {
        if (!Number.isInteger(data.job_id)) {
            return next(new Error('Grading start event does not contain a valid grading job id.'));
        }

        const params = {
            grading_job_id: data.job_id,
            start_time: data.data.start_time,
        };

        sqldb.queryOneRow(sql.update_grading_start_time, params, (err) => {
            if (ERR(err, (err) => logger.error(err))) return;
            externalGradingSocket.gradingLogStatusUpdated(data.job_id);
        });

        res.status(200);
        res.send();
    } else if (data.event === 'grading_result') {
        if (data.job_id === undefined || data.job_id === null || !Number.isInteger(data.job_id)) {
            return next(new Error('Grading result does not contain a valid grading job id.'));
        }

        // It's possible that the results data was specified in the body;
        // if that's the case, we can process it directly. Otherwise, we
        // have to download it from S3 first.

        if (data.data) {
            // We have the data!
            processResults(data.data)

        } else {
            // We should fetch it from S3, and then process it
            const params = {
                Bucket: config.externalGradingResultsS3Bucket,
                Key: `job_${data.job_id}.json`,
                ResponseContentType: 'application/json',
            }
            new AWS.S3().getObject(params, (err, data) => {
                if (ERR(err, (err) => logger.error(err))) return;
                processResults(JSON.parse(data.Body))
            });
        }

        res.status(200);
        res.send();
    } else {
        return next(new Error('Unknown event'));
    }
});

module.exports = router;
<commit_msg>Fixed linter errors in webhooks<commit_after>var ERR = require('async-stacktrace');
var express = require('express');
var router = express.Router();
var AWS = require('aws-sdk');

var config = require('../../lib/config');
var logger = require('../../lib/logger');
var assessments = require('../../assessments');
var sqldb = require('../../lib/sqldb');
var sqlLoader = require('../../lib/sql-loader');
var sql = sqlLoader.loadSqlEquiv(__filename);
var externalGradingSocket = require('../../lib/external-grading-socket');

// FIXME move this to assessments.js for better code reuse; pull the nice
// error-handling logic from messageQueue.js into this function as well
function processResults(data) {
    let gradingResult;
    if (!data.succeeded || !data.results) {
        gradingResult = {
            gradingId: data.job_id,
            grading: {
                startTime: data.start_time || null,
                endTime: data.end_time || null,
                score: 0,
                feedback: data
            }
        };
    } else {
        gradingResult = {
            gradingId: data.job_id,
            grading: {
                startTime: data.start_time || null,
                endTime: data.end_time || null,
                score: data.results.score,
                feedback: data
            }
        };
    }

    assessments.processGradingResult(gradingResult);
}

router.post('/', function(req, res, next) {

    const data = req.body;
    if (data.event === 'grading_start') {
        if (!Number.isInteger(data.job_id)) {
            return next(new Error('Grading start event does not contain a valid grading job id.'));
        }

        const params = {
            grading_job_id: data.job_id,
            start_time: data.data.start_time,
        };

        sqldb.queryOneRow(sql.update_grading_start_time, params, (err) => {
            if (ERR(err, (err) => logger.error(err))) return;
            externalGradingSocket.gradingLogStatusUpdated(data.job_id);
        });

        res.status(200);
        res.send();
    } else if (data.event === 'grading_result') {
        if (data.job_id === undefined || data.job_id === null || !Number.isInteger(data.job_id)) {
            return next(new Error('Grading result does not contain a valid grading job id.'));
        }

        // It's possible that the results data was specified in the body;
        // if that's the case, we can process it directly. Otherwise, we
        // have to download it from S3 first.

        if (data.data) {
            // We have the data!
            processResults(data.data);

        } else {
            // We should fetch it from S3, and then process it
            const params = {
                Bucket: config.externalGradingResultsS3Bucket,
                Key: `job_${data.job_id}.json`,
                ResponseContentType: 'application/json',
            };
            new AWS.S3().getObject(params, (err, data) => {
                if (ERR(err, (err) => logger.error(err))) return;
                processResults(JSON.parse(data.Body));
            });
        }

        res.status(200);
        res.send();
    } else {
        return next(new Error('Unknown event'));
    }
});

module.exports = router;

{'fraction_non_alphanumeric': 0.13181888425282026, 'fraction_numerical': 0.0033997836501313554, 'mean_word_length': 1.9512083903328774, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4710805', 'n_tokens_mistral': 1863, 'n_tokens_neox': 1789, 'n_words': 462}