-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathdeprecated.js
134 lines (115 loc) · 4.35 KB
/
deprecated.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Imports
var PromiseThrottle = require("promise-throttle");
var CryptoJS = require("crypto-js");
var soap = require("soap");
var _ = require("lodash")
//var WSDL = "https://mechanicalturk.amazonaws.com/AWSMechanicalTurk/AWSMechanicalTurkRequester.wsdl";
var WSDL = __dirname + "/schemas/AWSMechanicalTurkRequester-2014-08-15.wsdl";
var PRODUCTION = "https://mechanicalturk.amazonaws.com/";
var SANDBOX = "https://mechanicalturk.sandbox.amazonaws.com/";
var SERVICE = "AWSMechanicalTurkRequester";
//Throttles client requests to a rate-limited 3 request per second, makes sure mturk does not return
//503 errors when it is overwhealmed by multiple simultaneous requests (by requests in a for loop, for example)
var requestQueue = new PromiseThrottle({
requestsPerSecond: 3, // up to 1 request per second
promiseImplementation: Promise // the Promise library you are using
});
function MTurkAPI() {
var mturk = this;
mturk.createClient = mturk.connect = function (config) {
return new Promise(function (resolve, reject) {
soap.createClient(WSDL, function (err, SOAPClient) {
//Check that the SOAP client was created propery
if (err) {
console.error(err);
return reject(err)
}
//Configure client
var endPoint = config.sandbox ? SANDBOX : PRODUCTION;
SOAPClient.setEndpoint(endPoint);
//Get all the operations from the WSDL description
var operations = Object.keys(SOAPClient.AWSMechanicalTurkRequester.AWSMechanicalTurkRequesterPort);
//Build an API based on the client, config and WSDL description
var api = buildAPI(SOAPClient, config, operations);
//Main interface method
api.req = function (operation, params) {
params = params || {};
return new Promise(function (resolve, reject) {
requestQueue.add(request.bind(this, api, operation, params)).then(resolve).catch(reject);
})
};
resolve(api);
})
})
};
return mturk;
}
function request(api, operation, params) {
return new Promise(function (resolve, reject) {
//Check that request operation is valid, otherwise display error message
if (api[operation] && typeof api[operation] == "function") {
api[operation](params).then(resolve).catch(reject);
} else {
reject("Invalid Amazon Mechanical Turk API operation: '" + operation + "'. See the docs here: https://goo.gl/6RCpKU");
}
})
}
function buildAPI(client, config, operations) {
//Add a method for each available operation
var api = {};
_.forEach(operations, function (operation) {
api[operation] = function (params) {
params = params || {};
return new Promise(function (resolve, reject) {
client[operation](signRequest(config, operation, params), function (err, response) {
if (err) {
return reject(err)
}
var valid = isValidResponse(response);
valid ? resolve(response) : reject(getErrorMessage(response))
});
});
}
})
return api;
}
function signRequest(config, operation, parameters) {
var message = {};
message.Request = parameters;
message.AWSAccessKeyId = config.access || config.accessKeyId;
message.Timestamp = new Date().toISOString();
var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA1, config.secret || config.secretAccessKey);
hmac.update(SERVICE + operation + message.Timestamp);
message.Signature = hmac.finalize().toString(CryptoJS.enc.Base64);
return message;
}
function isValidResponse(res) {
var validationProperty = "IsValid";
var property = search(res, validationProperty);
if (_.isEmpty(property)) return false;
return property[0][validationProperty] === "True" ? true : false;
}
function getErrorMessage(res) {
var validationProperty = "Error";
var property = search(res, validationProperty);
//Default error message is the response itself
var defaultMsg = JSON.stringify(res, null, "\t");
if (_.isEmpty(property)) {
return new Error(defaultMsg);
}
var msg = property[0][validationProperty][0].Message || defaultMsg;
return new Error(msg);
}
function search(obj, key) {
if (_.has(obj, key)) {
return [obj];
}
var res = [];
_.forEach(obj, function (v) {
if (typeof v == "object" && (v = search(v, key)).length)
res.push.apply(res, v);
});
return res;
}
//EXPORT
module.exports = new MTurkAPI();