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)); |