Skip to content

Commit 13ba6c6

Browse files
Merge pull request #23 from abhishek97/runEnc
add support for enc parameter for POST: /runs
2 parents edbc594 + 93c97be commit 13ba6c6

File tree

4 files changed

+50
-5
lines changed

4 files changed

+50
-5
lines changed
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
alter table submissions
2-
add column outputs varchar[];
1+
alter table submissions add column outputs varchar[];

src/routes/api/run.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {SubmissionAttributes, Submissions, db} from '../../db/models'
55
import {RunJob, queueJob, successListener} from '../../rabbitmq/jobqueue'
66
import {isInvalidRunRequest} from '../../validators/SubmissionValidators'
77
import {upload} from '../../utils/s3'
8+
import {normalizeRunJob} from '../../utils'
89
import config = require('../../../config')
910

1011
const route: Router = Router()
@@ -110,6 +111,7 @@ const getRunPoolElement = function (body: RunRequestBody, res: Response): RunPoo
110111
* @apiParam {String(Base64)} input [Optional] stdin input for the program (encoded in base64)
111112
* @apiParam {Enum} mode [Optional] mode for request. Default = `sync`, see: https://github.com/coding-blocks/judge-api/issues/16
112113
* @apiParam {String)} callback [Optional] callback url for request. Required for `mode = callback`
114+
* @apiParam {String)} enc [Optional] Encoding type for stdin and source. Can be `url`|`base64`. Default = 'base64'
113115
*
114116
* @apiUse AvailableLangs
115117
*
@@ -151,14 +153,16 @@ route.post('/', (req, res, next) => {
151153
Submissions.create(<SubmissionAttributes>{
152154
lang: req.body.lang,
153155
start_time: new Date()
154-
}).then((submission: SubmissionAttributes) => {
156+
}).then(async (submission: SubmissionAttributes) => {
155157

156-
let queued = queueJob(<RunJob>{
158+
const job: RunJob = await normalizeRunJob({
157159
id: submission.id,
158160
source: req.body.source,
159161
lang: req.body.lang,
160162
stdin: req.body.stdin
161-
})
163+
}, req.body.enc)
164+
165+
let queued = queueJob(job)
162166

163167
// Put into pool and wait for judge-worker to respond
164168
runPool[submission.id] = getRunPoolElement(req.body, res)

src/utils/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {RunJob} from '../rabbitmq/jobqueue'
2+
import {download} from './s3'
3+
4+
/**
5+
* Normalizes the Run Job (effectively normalizes source and stdin to base64 immediate values)
6+
* @param {RunJob} job
7+
* @param {string} enc (Default = 'base64')
8+
* @returns {Promise<RunJob>} the normalized runJob
9+
*/
10+
export const normalizeRunJob = async function (job: RunJob, enc:string = 'base64') : Promise<RunJob> {
11+
switch (enc) {
12+
case 'url':
13+
const [source, stdin] = await Promise.all([download(job.source), download(job.stdin)])
14+
return {
15+
...job,
16+
source,
17+
stdin
18+
}
19+
default: return job
20+
}
21+
}

src/utils/s3.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Minio = require('minio')
22
import v4 = require('uuid/v4')
3+
import axios from 'axios'
34
import config = require('../../config')
45

56
const client = new Minio.Client({
@@ -17,11 +18,31 @@ export type savedFile = {
1718

1819
export const urlForFilename = (bucket: string, filename: string) : string => `http${config.S3.ssl ? 's': ''}://${config.S3.endpoint}/${bucket}/${filename}`
1920

21+
/**
22+
* Uploads an object to s3 encoded as json
23+
* @param {object} object
24+
* @param {string} filename The filename (Default = randomized)
25+
* @param {string} bucket The bucket name (Default = picked from config.json)
26+
* @returns {Promise<savedFile>} The etag and url for the file saved
27+
*/
2028
export const upload = function (object:object, filename:string = v4() + '.json' ,bucket:string = config.S3.bucket) : Promise<savedFile> {
2129
return new Promise((resolve, reject) => {
2230
client.putObject(bucket, filename, JSON.stringify(object), function(err, etag) {
2331
if (err) return reject(err)
2432
resolve({etag, url: urlForFilename(bucket, filename) })
2533
})
2634
})
35+
}
36+
37+
/**
38+
* Downloads a file from url and encodes it
39+
* @param {string} url
40+
* @param {string} enc (Default = 'base64')
41+
* @returns {Promise<string>} the downloaded file encoded as specified
42+
*/
43+
export const download = async function (url: string, enc: string = 'base64') : Promise<string> {
44+
if (!url) return ''
45+
46+
const {data} = await axios.get(url)
47+
return Buffer.from(data).toString(enc)
2748
}

0 commit comments

Comments
 (0)