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

Commit b2f8244

Browse files
committed
Merge branch 'dev' of https://github.com/cloudspokes/tc-api into dev
2 parents 802f8ae + 87c683c commit b2f8244

File tree

5 files changed

+126
-20
lines changed

5 files changed

+126
-20
lines changed

actions/challenges.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ var uploadForDevelopChallenge = function (api, connection, dbConnectionMap, next
15941594
//Note 2 - this will also cover the case of private challenges
15951595
//User will have role Submitter only if the user belongs to group of private challenge and is registered.
15961596
if (!rows[0].is_user_submitter_for_challenge) {
1597-
cb(new ForbiddenError('You cannot submit for this challenge as you are not a Submitter.'));
1597+
cb(new ForbiddenError('You cannot submit for this challenge as you are not a submitter.'));
15981598
return;
15991599
}
16001600

actions/rss.js

Lines changed: 83 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
/*
22
* Copyright (C) 2014 TopCoder Inc., All Rights Reserved.
33
*
4-
* @version 1.0
4+
* @version 1.1
55
* @author Ghost_141
6+
* Changes in 1.1:
7+
* - Add technologies and platforms filter.
68
*/
79
"use strict";
810

911
var async = require('async');
1012
var _ = require('underscore');
13+
var fs = require('fs');
1114
var BadRequestError = require('../errors/BadRequestError');
1215
var UnauthorizedError = require('../errors/UnauthorizedError');
1316
var ForbiddenError = require('../errors/ForbiddenError');
@@ -17,6 +20,38 @@ var ForbiddenError = require('../errors/ForbiddenError');
1720
*/
1821
var VALID_CHALLENGE_TYPE = ['develop', 'design', 'data'];
1922

23+
/**
24+
* The technology filter for challenges api.
25+
* @since 1.1
26+
*/
27+
var TECHNOLOGY_FILTER = ' AND EXISTS (SELECT DISTINCT 1 FROM comp_technology ct WHERE ct.comp_vers_id = pi1.value ' +
28+
'AND ct.technology_type_id IN (@filter@))';
29+
30+
/**
31+
* The platform filter for challenges api.
32+
* @since 1.1
33+
*/
34+
var PLATFORM_FILTER = ' AND EXISTS (SELECT 1 FROM project_platform pp WHERE pp.project_platform_id IN (@filter@) ' +
35+
'AND p.project_id = pp.project_id)';
36+
37+
/**
38+
* Add tech filter and platform filter.
39+
* @param query
40+
* @param techId
41+
* @param platformId
42+
* @param helper
43+
* @returns {*}
44+
*/
45+
function addFilter(query, techId, platformId, helper) {
46+
if (_.isDefined(techId)) {
47+
query = helper.editSql(query, TECHNOLOGY_FILTER, techId.join(','));
48+
}
49+
if (_.isDefined(platformId)) {
50+
query = helper.editSql(query, PLATFORM_FILTER, platformId.join(','));
51+
}
52+
return query;
53+
}
54+
2055
/**
2156
* Get the challenges RSS information.
2257
*
@@ -30,6 +65,10 @@ function getChallengesRSS(api, connection, next) {
3065
RSSMaxLength = api.config.tcConfig.maxRSSLength,
3166
positionsRemain = RSSMaxLength,
3267
challengeType = connection.params.challengeType,
68+
technologies = connection.params.technologies,
69+
techId,
70+
platforms = connection.params.platforms,
71+
platformId,
3372
listType = (connection.params.listType || helper.ListType.OPEN).toUpperCase(),
3473
copyToResult = function (queryResults) {
3574
if (positionsRemain > 0) {
@@ -68,51 +107,78 @@ function getChallengesRSS(api, connection, next) {
68107
error = helper.checkContains(VALID_CHALLENGE_TYPE, challengeType.toLowerCase(), 'challengeType');
69108
}
70109
error = error || helper.checkContains(helper.VALID_LIST_TYPE, listType, 'listType');
71-
if (error) {
72-
cb(error);
73-
return;
74-
}
75110

76111
challengeType = (challengeType || 'all').toLowerCase();
77-
112+
cb(error);
113+
},
114+
function (cb) {
115+
if (!_.isUndefined(technologies)) {
116+
helper.getCatalogCachedValue(technologies.split(','), dbConnectionMap, 'technologies', cb);
117+
} else {
118+
cb(null, null);
119+
}
120+
},
121+
function (id, cb) {
122+
if (_.isDefined(techId)) {
123+
techId = id;
124+
}
125+
if (!_.isUndefined(platforms)) {
126+
helper.getCatalogCachedValue(platforms.split(','), dbConnectionMap, 'platforms', cb);
127+
} else {
128+
cb(null, null);
129+
}
130+
},
131+
function (id, cb) {
132+
if (_.isDefined(id)) {
133+
platformId = id;
134+
}
135+
helper.readQuery('get_software_studio_challenges_rss', cb);
136+
},
137+
function (q, cb) {
138+
q = addFilter(q, techId, platformId, helper);
139+
// edit the sql
78140
async.parallel({
79141
design: function (cbx) {
80142
if (challengeType === 'design' || challengeType === 'all') {
81-
api.dataAccess.executeQuery('get_software_studio_challenges_rss',
143+
api.dataAccess.executeSqlQuery(q,
82144
{
83145
page_size: RSSMaxLength,
84146
project_status_id: helper.LIST_TYPE_PROJECT_STATUS_MAP[listType],
85147
project_type_id: helper.studio.category,
86148
registration_phase_status: helper.LIST_TYPE_REGISTRATION_STATUS_MAP[listType]
87-
}, dbConnectionMap, cbx);
149+
}, 'tcs_catalog', dbConnectionMap, cbx);
88150
} else {
89151
cbx();
90152
}
91153
},
92154
develop: function (cbx) {
93155
if (challengeType === 'develop' || challengeType === 'all') {
94-
api.dataAccess.executeQuery('get_software_studio_challenges_rss',
156+
api.dataAccess.executeSqlQuery(q,
95157
{
96158
page_size: RSSMaxLength,
97159
project_status_id: helper.LIST_TYPE_PROJECT_STATUS_MAP[listType],
98160
project_type_id: helper.software.category,
99161
registration_phase_status: helper.LIST_TYPE_REGISTRATION_STATUS_MAP[listType]
100-
}, dbConnectionMap, cbx);
162+
}, 'tcs_catalog', dbConnectionMap, cbx);
101163
} else {
102164
cbx();
103165
}
104166
},
105167
data: function (cbx) {
106-
if (challengeType === 'data' || challengeType === 'all') {
107-
if (listType === helper.ListType.PAST) {
108-
api.dataAccess.executeQuery('get_past_data_challenges_rss', { page_size: RSSMaxLength }, dbConnectionMap, cbx);
109-
} else if (listType === helper.ListType.OPEN || listType === helper.ListType.ACTIVE) {
110-
api.dataAccess.executeQuery('get_open_data_challenges_rss', { page_size: RSSMaxLength }, dbConnectionMap, cbx);
168+
if (_.isDefined(techId) || _.isDefined(platformId)) {
169+
cbx();
170+
} else {
171+
if (challengeType === 'data' || challengeType === 'all') {
172+
if (listType === helper.ListType.PAST) {
173+
api.dataAccess.executeQuery('get_past_data_challenges_rss', { page_size: RSSMaxLength }, dbConnectionMap, cbx);
174+
} else if (listType === helper.ListType.OPEN || listType === helper.ListType.ACTIVE) {
175+
api.dataAccess.executeQuery('get_open_data_challenges_rss', { page_size: RSSMaxLength }, dbConnectionMap, cbx);
176+
} else {
177+
cbx();
178+
}
111179
} else {
112180
cbx();
113181
}
114-
} else {
115-
cbx();
116182
}
117183
}
118184
}, cb);

initializers/helper.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/**
77
* This module contains helper functions.
88
* @author Sky_, Ghost_141, muzehyun, kurtrips, isv, LazyChild, hesibo, panoptimum, flytoj2ee
9-
* @version 1.37
9+
* @version 1.38
1010
* changes in 1.1:
1111
* - add mapProperties
1212
* changes in 1.2:
@@ -99,6 +99,8 @@
9999
* - Updated apiName2dbNameMap to add entries for registration_start_date and challenge_community columns
100100
* - Updated formatDateWithTimezone function to accept optional 'format' parameter.
101101
* - Updated checkDates function to accept optional 'errorMessage' parameter.
102+
* Changes in 1.38:
103+
* - Add method editSql, readQuery and constant QUERY_PATH.
102104
*/
103105
"use strict";
104106

@@ -1699,6 +1701,41 @@ helper.checkSortColumn = function (sortColumns, sortColumn) {
16991701
return null;
17001702
};
17011703

1704+
/**
1705+
* Add template into sql.
1706+
* @param {String} sql - the sql query.
1707+
* @param {String} template - the template that will insert into sql
1708+
* @param {String} content - the content that need in template.
1709+
* @since 1.38
1710+
*/
1711+
helper.editSql = function (sql, template, content) {
1712+
// For empty sql just return it.
1713+
if (sql.length === 0) {
1714+
return sql;
1715+
}
1716+
var index = sql.toLowerCase().indexOf('order by');
1717+
if (!_.isUndefined(template)) {
1718+
template = template.replace('@filter@', content);
1719+
}
1720+
return sql.slice(0, index) + template + sql.slice(index, sql.length);
1721+
};
1722+
1723+
/**
1724+
* The path that store all query files.
1725+
* @since 1.38
1726+
*/
1727+
helper.QUERY_PATH = './queries/';
1728+
1729+
/**
1730+
* Read the query from file name.
1731+
* @param {String} name - The file that store the query under queries folder.
1732+
* @param {Function} cb - The callback function.
1733+
* @since 1.38
1734+
*/
1735+
helper.readQuery = function (name, cb) {
1736+
fs.readFile(helper.QUERY_PATH + name, 'utf8', cb);
1737+
};
1738+
17021739
/*
17031740
* this is the random int generator class
17041741
*/

queries/get_software_studio_challenges_rss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ FIRST @page_size@
1010
, pcl.project_type_id
1111
FROM project p
1212
INNER JOIN project_category_lu pcl ON pcl.project_category_id = p.project_category_id
13+
INNER JOIN project_info pi1 ON pi1.project_id = p.project_id AND pi1.project_info_type_id = 1
1314
INNER JOIN project_info pi ON pi.project_info_type_id = 6 AND p.project_id = pi.project_id
1415
INNER JOIN project_phase pp1 ON pp1.project_id = p.project_id AND pp1.phase_type_id = 1
1516
LEFT JOIN project_spec ps ON ps.project_id = p.project_id and ps.version = (select max(version) from project_spec where project_id = p.project_id)

test/test.getChallengesRSS.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
/*
22
* Copyright (C) 2014 TopCoder Inc., All Rights Reserved.
33
*
4-
* @version 1.0
4+
* @version 1.1
55
* @author Ghost_141
6+
* Changes in 1.1:
7+
* - Add test case for technologies and platforms filter.
68
*/
79
'use strict';
810
/*global describe, it, before, beforeEach, after, afterEach */

0 commit comments

Comments
 (0)