207 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			207 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| (function (exports) {
 | |
|   'use strict';
 | |
| 
 | |
|   var DaplieApi;
 | |
|   var Oauth3 = (exports.OAUTH3 || require('./oauth3'));
 | |
| 
 | |
|   function realGet(conf, account, id, url) {
 | |
|     id = id || Math.random().toString();
 | |
| 
 | |
|     if (conf.promisesMap[id]) {
 | |
|       return conf.promisesMap[id];
 | |
|     }
 | |
| 
 | |
|     conf.promisesMap[id] = Oauth3.request({
 | |
|       url: url
 | |
|     , method: 'GET'
 | |
|     , headers: { 'Authorization': 'Bearer ' + account.token }
 | |
|     }).then(function (resp) {
 | |
|       delete conf.promisesMap[id];
 | |
| 
 | |
|       if (!resp.data) {
 | |
|         // This seems to happen on abort...
 | |
|         return Oauth3.PromiseA.reject("no data returned, the request may have been aborted");
 | |
|         //window.alert("[SANITY FAIL] '" + url + "' returned nothing (not even an error)");
 | |
|         //return;
 | |
|       }
 | |
| 
 | |
|       if (resp.data.error) {
 | |
|         console.error('[ERROR]', url);
 | |
|         console.error(resp.data);
 | |
|         window.alert("[DEVELOPER ERROR] '" + url + "' returned an error (is the url correct? did you check login first?)");
 | |
|         return Oauth3.PromiseA.reject("[DEVELOPER ERROR] '" + url + "' returned an error (is the url correct? did you check login first?)");
 | |
|       }
 | |
| 
 | |
| 
 | |
|       return resp.data;
 | |
|     }, function (err) {
 | |
|       delete conf.promisesMap[id];
 | |
| 
 | |
|       return Oauth3.PromiseA.reject(err);
 | |
|     });
 | |
| 
 | |
|     return conf.promisesMap[id];
 | |
|   }
 | |
| 
 | |
|   function promiseApiCall(conf, account, id, url, opts) {
 | |
|     opts = opts || {};
 | |
| 
 | |
|     function fetch() {
 | |
|       return new Oauth3.PromiseA(function (resolve, reject) {
 | |
|         var kotoken = setTimeout(function () {
 | |
|           if (opts.tried) {
 | |
|             reject(new Error("timed out (twice) when attempting to get data"));
 | |
|             return;
 | |
|           }
 | |
| 
 | |
|           opts.tried = true;
 | |
|           return promiseApiCall(account, id, url, opts).then(resolve, reject);
 | |
|         }, opts.tried && 16000 || 8000);
 | |
|         //opts.tried && 16000 || 8000
 | |
| 
 | |
|         realGet(conf, account, id, url).then(function (data) {
 | |
|           clearTimeout(kotoken);
 | |
|           resolve(data);
 | |
|         }, function (err) {
 | |
|           clearTimeout(kotoken);
 | |
|           reject(err);
 | |
|         });
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     if (!id) {
 | |
|       return fetch();
 | |
|     }
 | |
| 
 | |
|     return conf.cache.read(id, fetch, opts).then(function (data) {
 | |
|       // TODO, just data.value (after bugfix)
 | |
|       return data.value && data.value.value || data.value;
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   // TODO wrap with promises so that if a call is made before a prior call finishes,
 | |
|   // it's just one call
 | |
|   DaplieApi = {
 | |
|     create: function create(conf) {
 | |
|       // conf = { config, cache, session }
 | |
|       conf.promisesMap = {};
 | |
|       var myInstance = {};
 | |
| 
 | |
|       myInstance.accountsWithProfiles = function () {
 | |
|         var args = Array.prototype.slice.call(arguments);
 | |
|         args.unshift(conf);
 | |
|         return DaplieApi.accountsWithProfiles.apply(null, args);
 | |
|       };
 | |
|       myInstance.guessGender = DaplieApi.guessGender;
 | |
| 
 | |
|       Object.keys(DaplieApi.api).forEach(function (key) {
 | |
|         DaplieApi[key] = DaplieApi.api[key];
 | |
|       });
 | |
| 
 | |
|       Object.keys(DaplieApi.api).forEach(function (key) {
 | |
|         myInstance[key] = function () {
 | |
|           var args = Array.prototype.slice.call(arguments);
 | |
|           args.unshift(conf);
 | |
|           return DaplieApi.api[key].apply(null, args);
 | |
|         };
 | |
|       });
 | |
| 
 | |
|       return myInstance;
 | |
|     }
 | |
|   , accountsWithProfiles: function accountsWithProfiles(conf, accounts) {
 | |
|       // TODO conf.session.get()
 | |
|       var session = conf.session._conf.session;
 | |
|       var promises = [];
 | |
|       accounts = accounts || [];
 | |
| 
 | |
|       session.accounts.forEach(function (account) {
 | |
|         account = conf.session.cloneAccount(account);
 | |
| 
 | |
|         promises.push(DaplieApi.api.profile(conf, account).then(function (profile) {
 | |
|           // TODO get a slim profile?
 | |
|           account.profile = profile;
 | |
|           accounts.push(account);
 | |
|         }));
 | |
|       });
 | |
| 
 | |
|       return Oauth3.PromiseA.all(promises).then(function () {
 | |
|         // get the most recently added account as the first in the list
 | |
|         // (they should already be sorted this way)
 | |
|         accounts.sort(function (a, b) {
 | |
|           return new Date(b.addedAt).valueOf() - new Date(a.addedAt).valueOf();
 | |
|         });
 | |
| 
 | |
|         return accounts;
 | |
|       });
 | |
|     }
 | |
|   };
 | |
|   DaplieApi.api = {
 | |
|     create: function (conf, account) {
 | |
|       var accountInstance = {};
 | |
| 
 | |
|       account = account || conf.session.selectAccount();
 | |
| 
 | |
|       Object.keys(DaplieApi.api).forEach(function (key) {
 | |
|         accountInstance[key] = DaplieApi.api[key];
 | |
|       });
 | |
| 
 | |
|       Object.keys(DaplieApi.api).forEach(function (key) {
 | |
|         accountInstance[key] = function () {
 | |
|           var args = Array.prototype.slice.call(arguments);
 | |
|           args.unshift(account);
 | |
|           args.unshift(conf);
 | |
|           return DaplieApi.api[key].apply(null, args);
 | |
|         };
 | |
|       });
 | |
| 
 | |
|       return accountInstance;
 | |
|     }
 | |
|   , raw: function (conf, account, rawUrl, params, opts) {
 | |
|       params = params || {};
 | |
| 
 | |
|       if (!rawUrl) {
 | |
|         throw new Error("no rawUrl provided");
 | |
|       }
 | |
| 
 | |
|       Object.keys(params).forEach(function (key) {
 | |
|         var val = params[key];
 | |
|         rawUrl = rawUrl.replace(':' + key, encodeURIComponent(val));
 | |
|       });
 | |
| 
 | |
|       //rawUrl = rawUrl.replace(':account_id' + key, encodeURIComponent(val));
 | |
| 
 | |
|       var url = conf.config.apiBaseUri + conf.config.apiPrefix
 | |
|         + '/' + conf.session.getId(account) + rawUrl;
 | |
|       var id = url;
 | |
| 
 | |
|       return promiseApiCall(
 | |
|         conf
 | |
|       , account
 | |
|       , id
 | |
|       , url
 | |
|       , opts
 | |
|       );
 | |
|     }
 | |
|   //, me: function (conf, account, opts)
 | |
|   , profile: function (conf, account, opts) {
 | |
|       // NOTE: account may also be a session object with an accountId and token
 | |
|       var id = conf.session.getId(account) + '.me';
 | |
|       var url = conf.config.apiBaseUri + conf.config.apiPrefix
 | |
|         + '/accounts/' + conf.session.getId(account) + '/me';
 | |
| 
 | |
|       return promiseApiCall(
 | |
|         conf
 | |
|       , account
 | |
|       , id
 | |
|       , url
 | |
|       , opts
 | |
|       );
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   exports.DaplieApi = DaplieApi.DaplieApi = DaplieApi;
 | |
|   if ('undefined' !== typeof module) {
 | |
|     module.exports = DaplieApi;
 | |
|   }
 | |
| }('undefined' !== typeof exports ? exports : window));
 |