Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit 66977b5

Browse files
author
ykohata
committed
Merge remote-tracking branch 'origin/technology-2014-12-11'
2 parents 782003f + bd4226a commit 66977b5

35 files changed

+8152
-35
lines changed

actions/memberStatistics.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ function getBasicUserProfile(api, handle, privateInfoEligibility, dbConnectionMa
296296
address;
297297

298298
result = {
299+
uid: connection.caller.userId,
299300
handle: basic.handle,
300301
country: basic.country,
301302
memberSince: basic.member_since,

actions/rss.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,10 @@ function getChallengesRSS(api, connection, next) {
7979
challengeType: row.challenge_type.trim(),
8080
challengeName: row.challenge_name,
8181
challengeId: row.challenge_id,
82-
detailedRequirements: row.detailed_requirements || '',
8382
registrationStartDate: row.registration_start_date,
8483
challengeCommunity: row.challenge_community,
8584
projectId: row.project_id
8685
};
87-
if (_.isDefined(row.software_detailed_requirements)) {
88-
res.detailedRequirements = row.software_detailed_requirements || '';
89-
}
90-
if (_.isDefined(row.studio_detailed_requirements)) {
91-
res.detailedRequirements = row.studio_detailed_requirements || '';
92-
}
9386
if (row.project_type_id === helper.studio.category[0]) {
9487
res.challengeCommunity = helper.studio.community;
9588
} else {

actions/sourceCodeImage.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright (C) 2014 TopCoder Inc., All Rights Reserved.
3+
*
4+
* The api to convert the source code to image.
5+
*
6+
* @version 1.0
7+
* @author TCASSEMBLER
8+
*/
9+
/*jslint node: true, nomen: true, plusplus: true, unparam: true */
10+
"use strict";
11+
var async = require('async');
12+
var _ = require('underscore');
13+
var IllegalArgumentError = require('../errors/IllegalArgumentError');
14+
var highlight = require('highlight.js');
15+
var wkhtmltoimage = require('wkhtmltoimage');
16+
var BadRequestError = require('../errors/BadRequestError');
17+
var exec = require('child_process').exec;
18+
19+
// The style name array.
20+
var STYLE_NAMES = ['arta', 'ascetic', 'atelier-dune.dark', 'atelier-dune.light', 'atelier-forest.dark', 'atelier-forest.light',
21+
'atelier-heath.dark', 'atelier-heath.light', 'atelier-lakeside.dark', 'atelier-lakeside.light', 'atelier-seaside.dark',
22+
'atelier-seaside.light', 'brown_paper', 'codepen-embed', 'color-brewer', 'dark', 'default', 'docco',
23+
'far', 'foundation', 'github', 'googlecode', 'hybrid', 'idea', 'ir_black', 'kimbie.dark', 'kimbie.light', 'magula',
24+
'mono-blue', 'monokai', 'monokai_sublime', 'obsidian', 'paraiso.dark', 'paraiso.light', 'pojoaque', 'railscasts',
25+
'rainbow', 'school_book', 'solarized_dark', 'solarized_light', 'sunburst', 'tomorrow-night-blue',
26+
'tomorrow-night-bright', 'tomorrow-night-eighties', 'tomorrow-night', 'tomorrow', 'vs', 'xcode', 'zenburn'];
27+
28+
/**
29+
* Convert the source code to image.
30+
*
31+
* @param api - the api instance
32+
* @param connection - the request connection instance
33+
* @param next - the callback method.
34+
*/
35+
var convertSourceCodeToImage = function (api, connection, next) {
36+
var helper = api.helper,
37+
highlightResult = '',
38+
emptyStr = '',
39+
code = connection.params.code + emptyStr,
40+
style = connection.params.style,
41+
language = connection.params.lang;
42+
43+
async.waterfall([
44+
function (cb) {
45+
if (_.isNull(language) || _.isEmpty(language) || !highlight.getLanguage(language + emptyStr)) {
46+
cb(new IllegalArgumentError("The language name is invalid."));
47+
return;
48+
}
49+
50+
if (!_.isUndefined(style) && !_.isNull(style) && !_.isEmpty(style) && !_.contains(STYLE_NAMES, style + emptyStr)) {
51+
cb(new IllegalArgumentError("The style name is invalid."));
52+
return;
53+
}
54+
55+
exec(api.config.tcConfig.generateSourceCodeImage.wkhtmltoimageCommandPath + ' -H', function(error, stdout, stderr) {
56+
if (stderr !== null && stderr !== '') {
57+
cb(new IllegalArgumentError('The wkhtmltoimageCommandPath in configuration is invalid. The return error is ' + stderr));
58+
return;
59+
}
60+
cb();
61+
});
62+
}, function (cb) {
63+
var styleLink = api.config.tcConfig.generateSourceCodeImage.styleLink;
64+
if (!_.isUndefined(style) && !_.isNull(language) && !_.isEmpty(language)) {
65+
styleLink = styleLink.replace('%OVERRIDE_STYLE_NAME%', style);
66+
} else {
67+
styleLink = styleLink.replace('%OVERRIDE_STYLE_NAME%', 'default');
68+
}
69+
highlight.configure({ 'useBR': true });
70+
highlightResult = highlight.highlight(language, code, true).value;
71+
highlightResult = '<html><head><link rel="stylesheet" href="' + styleLink + '"></head><body><pre>' + highlightResult;
72+
highlightResult = highlightResult + '</pre></body></html>';
73+
cb();
74+
}, function (cb) {
75+
var response = connection.rawConnection.res,
76+
tempFileName = new Date().getTime() + (Math.floor(Math.random() * 1000) + '.jpg');
77+
78+
response.writeHead(200, {
79+
'Content-Type': 'image/jpeg',
80+
'Content-Disposition': 'inline; filename=' + tempFileName
81+
});
82+
83+
wkhtmltoimage.setCommand(api.config.tcConfig.generateSourceCodeImage.wkhtmltoimageCommandPath);
84+
wkhtmltoimage.generate(highlightResult, api.config.tcConfig.generateSourceCodeImage.wkhtmlToImageOptions, function (code, signal) {
85+
if (code !== null && code === 0) {
86+
// all success
87+
cb();
88+
} else {
89+
cb(new BadRequestError("Failed to generate the image, the return code is " + code));
90+
}
91+
92+
}).pipe(response);
93+
}
94+
], function (err) {
95+
if (err) {
96+
helper.handleError(api, connection, err);
97+
next(connection, true);
98+
} else {
99+
next(connection, false); //false = response has been set
100+
}
101+
});
102+
};
103+
104+
/**
105+
* The API for converted source code to image.
106+
*/
107+
exports.convertSourceCodeToImage = {
108+
name: "convertSourceCodeToImage",
109+
description: "Convert source code to image",
110+
inputs: {
111+
required: ['code', 'lang'],
112+
optional: ['style']
113+
},
114+
blockedConnectionTypes: [],
115+
cacheEnabled: false,
116+
outputExample: {},
117+
version: 'v2',
118+
run: function (api, connection, next) {
119+
api.log("Execute convertSourceCodeToImage#run", 'debug');
120+
convertSourceCodeToImage(api, connection, next);
121+
}
122+
};

actions/srmRoundQuestions.js

Lines changed: 170 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
/*
22
* Copyright (C) 2014 TopCoder Inc., All Rights Reserved.
33
*/
4-
/**
4+
/**
55
* - Implement the srm round questions / answers / survey api.
66
* Changes in version 1.1 (Module Assembly - Web Arena - Match Configurations):
77
* - Updated getRoundQuestions to send roundId with response
8+
* Changes in 1.2:
9+
* - Added actions for modifying/deleting round question answers.
810
*
9-
* @version 1.1
10-
* @author TCSASSEMBLER
11+
* @version 1.2
12+
* @author isv
1113
*/
1214

1315
/*jslint node: true, nomen: true, plusplus: true, stupid: true, unparam: true */
@@ -16,6 +18,7 @@ var async = require('async');
1618
var _ = require('underscore');
1719
var moment = require('moment');
1820
var IllegalArgumentError = require('../errors/IllegalArgumentError');
21+
var NotFoundError = require('../errors/NotFoundError');
1922

2023
var DATE_FORMAT = "YYYY-MM-DD HH:mm";
2124

@@ -327,7 +330,8 @@ function checkAnswerValues(api, text, sortOrder, correct, callback) {
327330
error = helper.checkStringParameter(text, "text", 250);
328331

329332
if (!error && _.isDefined(sortOrder)) {
330-
error = helper.checkPositiveInteger(sortOrder, "sortOrder");
333+
error = helper.checkPositiveInteger(sortOrder, "sortOrder")
334+
|| helper.checkMaxInt(sortOrder, "sortOrder");
331335
}
332336

333337
if (!error && _.isDefined(correct)) {
@@ -609,8 +613,8 @@ var modifyRoundQuestion = function (api, connection, dbConnectionMap, next) {
609613
*/
610614
var deleteRoundQuestion = function (api, connection, dbConnectionMap, next) {
611615
var helper = api.helper,
612-
sqlParams = {},
613-
questionId = Number(connection.params.questionId);
616+
sqlParams = {},
617+
questionId = Number(connection.params.questionId);
614618

615619
async.waterfall([
616620
function (cb) {
@@ -631,6 +635,115 @@ var deleteRoundQuestion = function (api, connection, dbConnectionMap, next) {
631635
});
632636
};
633637

638+
/**
639+
* Checks if answer with specified ID exists in database.
640+
*
641+
* @param api the api instance.
642+
* @param dbConnectionMap the database connection map.
643+
* @param answerId - the answerId parameter.
644+
* @param callback the callback method.
645+
*/
646+
function checkAnswerId(api, dbConnectionMap, answerId, callback) {
647+
var helper = api.helper,
648+
error = helper.checkIdParameter(answerId, "answerId");
649+
650+
async.waterfall([
651+
function (cb) {
652+
if (!error) {
653+
api.dataAccess.executeQuery("get_answer_id", {answerId: answerId}, dbConnectionMap, cb);
654+
} else {
655+
cb(null, null);
656+
}
657+
}, function (results, cb) {
658+
if (!error) {
659+
if (results.length === 0) {
660+
error = new NotFoundError("The answerId does not exist in database.");
661+
}
662+
}
663+
cb(error);
664+
}
665+
], function (err) {
666+
if (err) {
667+
callback(err);
668+
return;
669+
}
670+
671+
callback(null, error);
672+
});
673+
}
674+
675+
/**
676+
* Modify Round Question Answer.
677+
*
678+
* @param api the api instance.
679+
* @param connection the connection instance.
680+
* @param dbConnectionMap the database connection map.
681+
* @param next the callback method.
682+
*/
683+
var modifyRoundQuestionAnswer = function (api, connection, dbConnectionMap, next) {
684+
var helper = api.helper,
685+
sqlParams = {},
686+
answerId = Number(connection.params.answerId),
687+
text = connection.params.text,
688+
sortOrder = connection.params.sortOrder,
689+
correct = connection.params.correct;
690+
691+
async.waterfall([
692+
function (cb) {
693+
cb(helper.checkAdmin(connection, 'Authorized information needed.', 'Admin access only.'));
694+
}, function (cb) {
695+
checkAnswerValues(api, text, sortOrder, correct, cb);
696+
}, function (error, cb) {
697+
checkAnswerId(api, dbConnectionMap, answerId, cb);
698+
}, function (error, cb) {
699+
sqlParams.answerId = answerId;
700+
sqlParams.answerText = text;
701+
sqlParams.sortOrder = sortOrder;
702+
sqlParams.correct = (correct === true || correct.toLowerCase() === "true") ? 1 : 0;
703+
api.dataAccess.executeQuery("update_answer", sqlParams, dbConnectionMap, cb);
704+
}
705+
], function (err) {
706+
if (err) {
707+
helper.handleError(api, connection, err);
708+
} else {
709+
connection.response = {"success": true};
710+
}
711+
next(connection, true);
712+
});
713+
};
714+
715+
/**
716+
* Delete Round Question Answer.
717+
*
718+
* @param api the api instance.
719+
* @param connection the connection instance.
720+
* @param dbConnectionMap the database connection map.
721+
* @param next the callback method.
722+
*/
723+
var deleteRoundQuestionAnswer = function (api, connection, dbConnectionMap, next) {
724+
var helper = api.helper,
725+
sqlParams = {},
726+
answerId = Number(connection.params.answerId);
727+
728+
async.waterfall([
729+
function (cb) {
730+
cb(helper.checkAdmin(connection, 'Authorized information needed.', 'Admin access only.'));
731+
}, function (cb) {
732+
cb(helper.checkIdParameter(answerId, 'answerId'));
733+
}, function (cb) {
734+
sqlParams.answerId = answerId;
735+
api.dataAccess.executeQuery("delete_answer", sqlParams, dbConnectionMap, cb);
736+
}
737+
], function (err, result) {
738+
if (err) {
739+
helper.handleError(api, connection, err);
740+
} else {
741+
connection.response = {"success": result > 0};
742+
}
743+
next(connection, true);
744+
});
745+
};
746+
634747
/**
635748
* The API for get Round Questions API.
636749
*/
@@ -802,3 +915,54 @@ exports.deleteRoundQuestion = {
802915
}
803916
}
804917
};
918+
919+
920+
/**
921+
* The API for Modify Round Question Answer API.
922+
*/
923+
exports.modifyRoundQuestionAnswer = {
924+
name: "modifyRoundQuestionAnswer",
925+
description: "Modify Round Question Answer",
926+
inputs: {
927+
required: ['answerId', 'text', 'sortOrder', 'correct'],
928+
optional: []
929+
},
930+
blockedConnectionTypes: [],
931+
outputExample: {},
932+
version: 'v2',
933+
transaction: 'write',
934+
databases: ["informixoltp"],
935+
run: function (api, connection, next) {
936+
if (connection.dbConnectionMap) {
937+
api.log("Execute modifyRoundQuestionAnswer#run", 'debug');
938+
modifyRoundQuestionAnswer(api, connection, connection.dbConnectionMap, next);
939+
} else {
940+
api.helper.handleNoConnection(api, connection, next);
941+
}
942+
}
943+
};
944+
945+
/**
946+
* The API for Delete Round Question Answer API.
947+
*/
948+
exports.deleteRoundQuestionAnswer = {
949+
name: "deleteRoundQuestionAnswer",
950+
description: "Delete Round Question Answer",
951+
inputs: {
952+
required: ['answerId'],
953+
optional: []
954+
},
955+
blockedConnectionTypes: [],
956+
outputExample: {},
957+
version: 'v2',
958+
transaction: 'write',
959+
databases: ["informixoltp"],
960+
run: function (api, connection, next) {
961+
if (connection.dbConnectionMap) {
962+
api.log("Execute deleteRoundQuestionAnswer#run", 'debug');
963+
deleteRoundQuestionAnswer(api, connection, connection.dbConnectionMap, next);
964+
} else {
965+
api.helper.handleNoConnection(api, connection, next);
966+
}
967+
}
968+
};

actions/user.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,10 +365,14 @@ function getUserIdentityByAuth0Id(api, connection, next) {
365365
}
366366
},
367367
function (result, cb) {
368+
if (!result[0]) {
369+
cb(notfound);
370+
} else {
368371
userid = result[0].user_id
369372
api.dataAccess.executeQuery('get_user_email_and_handle',
370373
{ userId: userid },
371374
dbConnectionMap, cb);
375+
}
372376
},
373377
function (rs, cb) {
374378
if (!rs[0]) {

0 commit comments

Comments
 (0)