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

James users api data #170

Merged
merged 5 commits into from
Apr 3, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 90 additions & 78 deletions actions/memberStatistics.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/*
* Copyright (C) 2013 - 2014 TopCoder Inc., All Rights Reserved.
*
* @version 1.14
* @author Sky_, Ghost_141, muzehyun, hesibo, isv, LazyChild
* @version 1.15
* @author Sky_, Ghost_141, muzehyun, hesibo, isv, LazyChild, jamestc
* changes in 1.1:
* - implement marathon statistics
* changes in 1.2:
Expand Down Expand Up @@ -36,6 +36,8 @@
* changes in 1.14
* - added my profile api
* - modified public profile api(basic user profile api), only return public information
* changes in 1.15
* - enabled granular data access in getBasicUserProfile via optional query param
*/
"use strict";
var async = require('async');
Expand Down Expand Up @@ -118,6 +120,24 @@ function getBasicUserProfile(api, handle, privateInfoEligibility, dbConnectionMa
},
result;

var loadData;
// check for an optional data query string param than enables loading a subset of data
var requestedData = connection.rawConnection.parsedURL.query.data;
if (_.isDefined(requestedData)) {
// NOTE: an empty value is acceptable and indicates only basic data is returned
loadData = {};
if (requestedData) {
// data is comma delimited string of requested data
var parts = requestedData.split(',');
_.each(parts, function (part) {
loadData[part] = true;
});
}
api.log("Requested data param found: " + requestedData, "debug");
} else {
loadData = {earnings:true, ratings:true, achievements:true, address:true, email:true}; // load all data by default
}

async.waterfall([
function (cb) {
if (privateInfoEligibility) {
Expand All @@ -139,103 +159,95 @@ function getBasicUserProfile(api, handle, privateInfoEligibility, dbConnectionMa
};
async.parallel({
basic: execQuery('basic'),
earning: execQuery('overall_earning'),
ratingSummary: execQuery('rating_summary'),
achievements: execQuery('achievements'),
privateInfo: privateInfoEligibility ? execQuery('private') : function (cbx) { cbx(); },
emails: privateInfoEligibility ? execQuery('private_email') : function (cbx) { cbx(); }
earning: loadData.earnings ? execQuery('overall_earning') : function(cbx) { cbx(); },
ratingSummary: loadData.ratings ? execQuery('rating_summary') : function(cbx) { cbx(); },
achievements: loadData.achievements ? execQuery('achievements') : function(cbx) { cbx(); },
privateInfo: loadData.address && privateInfoEligibility ? execQuery('private') : function (cbx) { cbx(); },
emails: loadData.email && privateInfoEligibility ? execQuery('private_email') : function (cbx) { cbx(); }
}, cb);
}, function (results, cb) {
var basic = results.basic[0], earning = results.earning[0], ratingSummary = results.ratingSummary,
achievements = results.achievements, privateInfo,
mapRatingSummary = function (ratings) {
var ret = [];
ratings.forEach(function (item) {
ret.push({
name: helper.getPhaseName(item.phase_id),
rating: item.rating,
colorStyle: helper.getColorStyle(item.rating)
});
var basic = results.basic[0];

result = {
handle: basic.handle,
country: basic.country,
memberSince: basic.member_since,
quote: basic.quote,
photoLink: basic.photo_link || ''
};

if (loadData.earnings && _.isDefined(basic.show_earnings) && basic.show_earnings !== 'hide') {
result.overallEarning = results.earning[0].overall_earning;
}

if (loadData.ratings) {
var ratingSummary = [];
results.ratingSummary.forEach(function (item) {
ratingSummary.push({
name: helper.getPhaseName(item.phase_id),
rating: item.rating,
colorStyle: helper.getColorStyle(item.rating)
});
return ret;
},
mapAchievements = function (achievements) {
var ret = [], achieveItem;
achievements.forEach(function (item) {
achieveItem = {
date: item.achievement_date,
description: item.description
};
ret.push(achieveItem);
});
result.ratingSummary = ratingSummary;
}

if (loadData.achievements) {
var achievements = [];
results.achievements.forEach(function (item) {
achievements.push({
date: item.achievement_date,
description: item.description
});
return ret;
},
mapEmails = function (emails) {
var ret = [];
emails.forEach(function (item) {
ret.push({
email: item.email,
type: item.type,
status: item.status
});
});
// TODO: why is this capitalized?
result.Achievements = achievements;
}

if (privateInfoEligibility && loadData.email) {
var emails = [];
results.emails.forEach(function (item) {
emails.push({
email: item.email,
type: item.type,
status: item.status
});
return ret;
},
appendIfNotEmpty = function (str) {
});
result.emails = emails;
}

if (privateInfoEligibility && loadData.address && results.privateInfo && results.privateInfo[0]) {
var appendIfNotEmpty = function (str) {
var ret = '';
if (str && str.length > 0) {
ret += ', ' + str;
}
return ret;
},
getAddressString = function (privateInfo) {
var address = privateInfo.address1;
if (!address) { return undefined; } // if address1 is undefined, there is no address.
};

var privateInfo = results.privateInfo[0];

result.name = privateInfo.first_name + ' ' + privateInfo.last_name;
result.age = privateInfo.age;
result.gender = privateInfo.gender;
result.shirtSize = privateInfo.shirt_size;

var address = privateInfo.address1;
// if address1 is undefined, there is no address.
if (address) {
address += appendIfNotEmpty(privateInfo.address2);
address += appendIfNotEmpty(privateInfo.address3);
address += ', ' + privateInfo.city;
address += appendIfNotEmpty(privateInfo.state);
address += ', ' + privateInfo.zip + ', ' + privateInfo.country;
return address;
};
result = {
handle: basic.handle,
country: basic.country,
memberSince: basic.member_since,
overallEarning: earning.overall_earning,
quote: basic.quote,
photoLink: basic.photo_link || '',
isCopilot: {
value: basic.is_copilot,
software: basic.is_software_copilot,
studio: basic.is_studio_copilot
},
isPM: basic.is_pm,

ratingSummary: mapRatingSummary(ratingSummary),
Achievements: mapAchievements(achievements)
};

if (!_.isDefined(basic.show_earnings) || basic.show_earnings === 'hide') {
delete result.overallEarning;
result.address = address;
}
}

if (result.isPM) {
delete result.ratingSummary;
}

if (privateInfoEligibility) {
result.emails = mapEmails(results.emails);
if (results.privateInfo && results.privateInfo[0]) {
privateInfo = results.privateInfo[0];
result.name = privateInfo.first_name + ' ' + privateInfo.last_name;
result.address = getAddressString(privateInfo);
result.age = privateInfo.age;
result.gender = privateInfo.gender;
result.shirtSize = privateInfo.shirt_size;
}
}
cb();
}
], function (err) {
Expand Down Expand Up @@ -1094,4 +1106,4 @@ exports.getMyProfile = {
api.helper.handleNoConnection(api, connection, next);
}
}
};
};
2 changes: 1 addition & 1 deletion config.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ config.tasks = {
// ['high,low'] is one worker working 2 queues
queues: ['default'],
// how long to sleep between jobs / scheduler checks
timeout: 5000,
timeout: process.env.TASK_TIMEOUT || 5000,
// What redis server should we connect to for tasks / delayed jobs?
redis: config.redis
};
Expand Down
15 changes: 0 additions & 15 deletions queries/get_user_basic_profile_basic
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,18 @@ SELECT
, c.country_name AS country
, co.member_since
, co.quote
, (CASE WHEN r.rating < 0
THEN 't'
ELSE 'f'
END)::boolean AS is_pm
, (CASE WHEN cp.user_id>0
THEN 't'
ELSE 'f'
END)::boolean AS is_copilot
, NVL(cp.is_software_copilot, 'f') AS is_software_copilot
, NVL(cp.is_studio_copilot, 'f') AS is_studio_copilot
, p.path || i.file_name AS photo_link
, up.value AS show_earnings
FROM user u
, coder co
, OUTER algo_rating r
, OUTER country c
, OUTER tcs_catalog:copilot_profile AS cp
, OUTER(coder_image_xref cix
, image i
, path p)
, OUTER user_preference up
WHERE u.handle_lower = LOWER('@handle@')
AND u.status = 'A'
AND u.user_id = cp.user_id
AND u.user_id = co.coder_id
AND u.user_id = r.coder_id
AND r.algo_rating_type_id = 1
AND u.user_id = cix.coder_id
AND c.country_code = co.comp_country_code
AND cix.display_flag = 1
Expand Down
60 changes: 57 additions & 3 deletions test/test.basicUserProfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@ describe('Get Basic User Profile API', function () {
var body = res.body, expected = require(name);
delete body.serverInformation;
delete body.requesterInformation;
body.Achievements.forEach(function (item) {
delete item.date;
});
if (body.Achievements) {
body.Achievements.forEach(function (item) {
delete item.date;
});
}
assert.deepEqual(body, expected);
cb();
});
Expand All @@ -120,6 +122,51 @@ describe('Get Basic User Profile API', function () {
assertBasicUserProfile('/v2/users/heffan', './test_files/expected_basic_user_profile_heffan', done);
});

/**
* Test /v2/users/heffan?data=
* Should return success results for heffan without earnings, ratings and achievements.
*/
it('should return success results for heffan without earning, ratings and achievements', function (done) {
assertBasicUserProfile('/v2/users/heffan?data=', './test_files/expected_basic_user_profile_heffan_no_data', done);
});

/**
* Test /v2/users/heffan?data=achievements
* Should return success results for heffan with just achievements
*/
it('should return success results for heffan with just achievements', function (done) {
assertBasicUserProfile('/v2/users/heffan?data=achievements', './test_files/expected_basic_user_profile_heffan_ach', done);
});

/**
* Test /v2/users/heffan?data=rating
* Should return success results for heffan with just rating summary
*/
it('should return success results for heffan with just ratings', function (done) {
assertBasicUserProfile('/v2/users/heffan?data=ratings', './test_files/expected_basic_user_profile_heffan_ratings', done);
});

/**
* Test /v2/users/heffan?data=earnings,rating
* should show overallEarning and rating fields in the response.
*/
it('should show earnings and rating', function (done) {
async.waterfall([
function (cb) {
testHelper.runSqlFile(SQL_DIR + 'informixoltp__update_show_earning', 'informixoltp', cb);
},
function (cb) {
assertBasicUserProfile('/v2/users/heffan?data=earnings,ratings', './test_files/expected_basic_user_profile_heffan_earning_ratings', cb);
}
], function (err) {
if (err) {
done(err);
return;
}
done();
});
});

/**
* Test /v2/users/super.
* Should return success results for super.
Expand All @@ -132,6 +179,7 @@ describe('Get Basic User Profile API', function () {
* Test /v2/users/heffan.
* The heffan is now be upgraded to software copilot. The isCopilot.software should be true now.
*/
/* isCopilot removed
it('should be a software copilot', function (done) {
async.waterfall([
function (cb) {
Expand Down Expand Up @@ -161,11 +209,13 @@ describe('Get Basic User Profile API', function () {
done();
});
});
*/

/**
* Test /v2/users/heffan.
* heffan has been upgraded to studio copilot. The isCopilot.studio should be true now.
*/
/* isCopilot removed
it('should be a studio copilot', function (done) {
async.waterfall([
function (cb) {
Expand Down Expand Up @@ -195,11 +245,13 @@ describe('Get Basic User Profile API', function () {
done();
});
});
*/

/**
* Test /v2/users/heffan.
* heffan is PM now. So the rating summary data should not be showed.
*/
/* isPM removed
it('should show no rating summary data', function (done) {
async.waterfall([
function (cb) {
Expand All @@ -216,6 +268,8 @@ describe('Get Basic User Profile API', function () {
done();
});
});
*/


/**
* Test /v2/users/heffan
Expand Down
6 changes: 0 additions & 6 deletions test/test_files/expected_basic_user_profile_heffan.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@
"memberSince": "2001-05-09T01:04:42.000Z",
"quote": "Acknowledge and move on.",
"photoLink": "/i/m/test_image.png",
"isCopilot": {
"value": true,
"software": false,
"studio": false
},
"isPM": false,
"ratingSummary": [
{
"name": "Design",
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy