PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/client/js-client/src/rlClient.js

https://gitlab.com/varunkothamachu/seldon-server
JavaScript | 363 lines | 322 code | 30 blank | 11 comment | 35 complexity | 9fc6bc2299b9494bea14b78e64d0b125 MD5 | raw file
  1. /*global reqwest:false, underscore:false, window:false, document:false */
  2. var rlClient = (function () {
  3. "use strict";
  4. var ajax = reqwest,
  5. // Configurable parameters (see init function below)
  6. params = {
  7. // default endpoint
  8. endpoint: "http://localhost:8080/api-server",
  9. // consumer name
  10. consumer: "",
  11. // query keys to retain when constructing an item id
  12. retain: [],
  13. // url rewrite rules (list of objects)
  14. rewrite: [],
  15. // the delimiter for the rlabs tag i.e. hash in example.com#rlabs=1
  16. rlabs_delim: "?",
  17. // the tag to look for when deciding whether this page view has come from
  18. // a rec click
  19. track_par: "rlabs",
  20. // possible track pars (to remove??)
  21. track_par_list: ["rlabs", "zehtg"],
  22. // not sure
  23. query_delimiter: "?",
  24. rectag_name: "rectag",
  25. use_pos_name: "use_pos",
  26. current_page_url: location.href
  27. };
  28. function extractQuery(paramString) {
  29. var q_params = {};
  30. underscore.each(paramString.split("&"), function (pair) {
  31. var x = pair.split("=");
  32. q_params[x[0]] = x[1];
  33. });
  34. return q_params;
  35. }
  36. function retrieveSeldonParamsFromURL() {
  37. var normalised = params.current_page_url,
  38. retVal,
  39. rlabs,
  40. query_params,
  41. query = normalised.replace(new RegExp(".*\\" + params.rlabs_delim), "");
  42. if (params.rlabs_delim === "?") {
  43. // removing final # if present in the query parameter
  44. query = query.replace(new RegExp("#" + ".*"), "");
  45. }
  46. if (query !== "") {
  47. query_params = extractQuery(query);
  48. underscore.each(params.track_par_list, function (par) {
  49. var val = query_params[par];
  50. if (val) {
  51. rlabs = val;
  52. }
  53. });
  54. }
  55. retVal = rlabs ? rlabs.split("%20") : [];
  56. return retVal;
  57. }
  58. function extractExtraSeldonParams(param_list) {
  59. var i, retVal = {};
  60. if (param_list.length > 1) {
  61. for (i = 1; i < param_list.length; i += 1) {
  62. retVal[param_list[i].split('$')[0]] = param_list[i].split('$')[1];
  63. }
  64. }
  65. return retVal;
  66. }
  67. function parameterString(params, keep) {
  68. var preserved = underscore.chain(underscore.keys(params).sort())
  69. .filter(function (x) {
  70. return underscore.contains(keep, x);
  71. })
  72. .map(function (key) {
  73. return key + "=" + params[key];
  74. })
  75. .value();
  76. if (preserved.length > 0) {
  77. return params.query_delimiter + preserved.join("&");
  78. }
  79. return "";
  80. }
  81. function rewrite(url, rules) {
  82. var rewritten = url;
  83. underscore.each(rules, function (rule) {
  84. underscore.each(rule, function (focus) {
  85. var focusRx = new RegExp(focus);
  86. if (url.match(focusRx)) {
  87. rewritten = rewritten.replace(focusRx, rule[focus]);
  88. }
  89. });
  90. });
  91. return rewritten;
  92. }
  93. function normalise(input) {
  94. var normalised, delim = "#";
  95. if (params.query_delimiter === "#") {
  96. delim = "?";
  97. }
  98. normalised = input.replace(new RegExp("\\" + delim + ".*"), "").replace(/[+ ]/, "%20", "g");
  99. return rewrite(normalised, params.rewrite);
  100. }
  101. function pageId(url, keep) {
  102. var normalised = normalise(url),
  103. source = normalised.replace(new RegExp("\\" + params.query_delimiter + ".*"), ""),
  104. paramString = normalised.replace(new RegExp(".*\\" + params.query_delimiter), ""),
  105. q_params = paramString ? extractQuery(paramString) : {},
  106. outParams = parameterString(q_params, keep),
  107. page_id = source + outParams;
  108. return encodeURIComponent(page_id);
  109. }
  110. function currentPageId(keep) {
  111. return pageId(params.current_page_url, keep);
  112. }
  113. function fullEndpoint(path) {
  114. return params.endpoint + path + "?consumer_key=" + params.consumer;
  115. }
  116. function actionUrl(type, user_id, item_id, rlabs, source, rectag, position) {
  117. return fullEndpoint("/js/action/new") +
  118. "&type=" + type +
  119. "&user=" + user_id +
  120. "&item=" + item_id +
  121. (rlabs ? ("&" + params.track_par + "=" + rlabs) : "") +
  122. (rectag ? ("&rectag=" + rectag) : "") +
  123. (source ? ("&source=" + encodeURIComponent(normalise(source))) : "") +
  124. (position ? ("&pos=" + position) : "");
  125. }
  126. function userUrl(user_id, facebook_opts) {
  127. return fullEndpoint("/js/user/new") +
  128. "&id=" + user_id +
  129. "&fb=" + (facebook_opts.facebook || "") +
  130. "&fbId=" + (facebook_opts.facebook_id || "") +
  131. "&fbToken=" + (facebook_opts.facebook_token || "");
  132. }
  133. function itemUrl(item_id, title, type) {
  134. return fullEndpoint("/js/item/new") +
  135. "&id=" + item_id +
  136. "&title=" + (title || "") +
  137. "&type=" + type;
  138. }
  139. function recommendedUsersUrl(user_id, item_id) {
  140. return fullEndpoint("/js/share") +
  141. "&user=" + user_id +
  142. "&item=" + item_id;
  143. }
  144. function attributeString(attributeNames) {
  145. return attributeNames.join(",");
  146. }
  147. function recommendationsUrl(user_id, item_id, rlabs, rectag, options) {
  148. return fullEndpoint("/js/recommendations") +
  149. "&user=" + user_id +
  150. "&item=" + item_id +
  151. "&dimensions=" + ((options.dimensions) || (options.dimension || 0)) +
  152. "&limit=" + (options.limit || 10) +
  153. (options.attributes ? ("&attributes=" + attributeString(options.attributes)) : "") +
  154. (options.algorithms ? "&algorithms=" + options.algorithms : "") +
  155. (rectag ? ("&rectag=" + rectag) : "") +
  156. (rlabs ? ("&" + params.track_par + "=" + rlabs) : "") +
  157. (options.cohort ? ("&cohort=" + options.cohort) : "");
  158. }
  159. function jsonpCall(url, callback) {
  160. var stamp = new Date().getTime(),
  161. stamped = url + (url.match(/\?/) ? "&" : "?") + "timestamp=" + stamp;
  162. ajax({
  163. url: stamped,
  164. type: 'jsonp',
  165. jsonpCallback: 'jsonpCallback',
  166. success: callback
  167. });
  168. }
  169. function withMandatory(name, value, callback) {
  170. if (!value) {
  171. return { fired: false, message: "No " + name + " specified." };
  172. }
  173. callback();
  174. return { fired: true };
  175. }
  176. function addAction(type, callback, user_id, item_id, rlabs, source, rectag, pos) {
  177. return withMandatory("user_id", user_id, function () {
  178. var urlparams = retrieveSeldonParamsFromURL(),
  179. id = item_id || currentPageId(params.retain),
  180. recId = rlabs || urlparams[0],
  181. tag = rectag || extractExtraSeldonParams(urlparams).rt,
  182. position = pos || extractExtraSeldonParams(urlparams).p,
  183. url;
  184. url = actionUrl(type, user_id, id, recId, source, tag, position);
  185. jsonpCall(url, callback);
  186. });
  187. }
  188. function recommendedUsers(user_id, item_id, callback) {
  189. return withMandatory("user_id", user_id, function () {
  190. var id = item_id || currentPageId(params.retain),
  191. url = recommendedUsersUrl(user_id, id);
  192. jsonpCall(url, callback);
  193. });
  194. }
  195. function addUser(user_id, options, callback) {
  196. return withMandatory("user_id", user_id, function () {
  197. var url = userUrl(user_id, options || {});
  198. jsonpCall(url, callback);
  199. });
  200. }
  201. function addItem(item_id, type, title, callback) {
  202. return withMandatory("item_id", item_id, function () {
  203. var url = itemUrl(item_id, title, type);
  204. jsonpCall(url, callback);
  205. });
  206. }
  207. function recommendationsFor(user_id, callback, options) {
  208. return withMandatory("user_id", user_id, function () {
  209. var itemId = options.item || currentPageId(params.retain),
  210. paramsFromURL = retrieveSeldonParamsFromURL(),
  211. rlabs = options[params.track_par] || paramsFromURL[0],
  212. rectag = options[params.rectag_name] || extractExtraSeldonParams(paramsFromURL).rt,
  213. url = recommendationsUrl(user_id, itemId, rlabs, rectag, options);
  214. jsonpCall(url, callback);
  215. });
  216. }
  217. function appendClickTo(items, options) {
  218. var delim = params.rlabs_delim,
  219. rectag = options[params.rectag_name],
  220. use_pos = options[params.use_pos_name],
  221. pos = 0;
  222. underscore.each(items, function (item) {
  223. var id = item.id,
  224. uuid = item.attributesName.recommendationUuid;
  225. if (uuid) {
  226. id += id.match(new RegExp("\\" + params.query_delimiter)) ? "&" : delim;
  227. id += params.track_par + "=" + uuid;
  228. if (rectag) {
  229. id += "%20rt$" + rectag;
  230. }
  231. if (use_pos) {
  232. pos += 1;
  233. id += "%20p$" + pos;
  234. }
  235. }
  236. item.id = id;
  237. });
  238. }
  239. function recommendationsStatic(callback, options, dimension) {
  240. var o = options || {},
  241. url = "https://s3-eu-west-1.amazonaws.com/rl-static/" + params.consumer + ".json?jsonpCallback=unused";
  242. if (dimension) {
  243. url = "https://s3-eu-west-1.amazonaws.com/rl-static/" + params.consumer + "-" + dimension + ".json?jsonpCallback=unused";
  244. }
  245. ajax({
  246. url: url,
  247. type: 'jsonp',
  248. jsonpCallback: 'jsonpCallback',
  249. success: function (response) {
  250. var recommendations = [];
  251. if (response.error_id === undefined) {
  252. recommendations = response.list;
  253. if (o.appendClick) {
  254. appendClickTo(recommendations, options);
  255. }
  256. }
  257. callback(recommendations);
  258. }
  259. });
  260. }
  261. function recommendationsStaticCustomUrl(custom_url, callback, options) {
  262. var o = options || {},
  263. stamp = new Date().getTime();
  264. custom_url = custom_url + (custom_url.match(/\?/) ? "&" : "?") + "timestamp=" + stamp + "&jsonpCallback=unused";
  265. ajax({
  266. url: custom_url,
  267. type: 'jsonp',
  268. jsonpCallback: 'jsonpCallback',
  269. success: function (response) {
  270. var recommendations_list = [],
  271. cohort = "-";
  272. if ((response !== null) && (response !== undefined) && (response.error_id === undefined)) {
  273. if (response.list) {
  274. recommendations_list = response.list;
  275. } else {
  276. recommendations_list = response.recommendedItems;
  277. cohort = response.cohort;
  278. }
  279. if (o.appendClick) {
  280. appendClickTo(recommendations_list, options);
  281. }
  282. }
  283. callback({recs: recommendations_list, cohort: cohort, service_type: "fallback"});
  284. }
  285. });
  286. }
  287. function recommendations(user_id, callback, options) {
  288. var o = options || {};
  289. return recommendationsFor(user_id, function (response) {
  290. var recommendations_list = [],
  291. cohort = "-";
  292. if ((response !== null) && (response !== undefined) && (response.error_id === undefined)) {
  293. if (response.list) {
  294. recommendations_list = response.list;
  295. } else {
  296. recommendations_list = response.recommendedItems;
  297. cohort = response.cohort;
  298. }
  299. if (o.appendClick) {
  300. appendClickTo(recommendations_list, options);
  301. }
  302. }
  303. callback({recs: recommendations_list, cohort: cohort});
  304. }, o);
  305. }
  306. return {
  307. init: function (overrides) {
  308. underscore.each(overrides, function (val, key) {
  309. params[key] = val;
  310. });
  311. },
  312. pageId: pageId,
  313. endpoint: function () {
  314. return params.endpoint;
  315. },
  316. addUser: addUser,
  317. addItem: addItem,
  318. recommendedUsers: recommendedUsers,
  319. addAction: addAction,
  320. recommendations: recommendations,
  321. recommendationsStatic: recommendationsStatic,
  322. recommendationsStaticCustomUrl: recommendationsStaticCustomUrl
  323. };
  324. }());