Skip to content

Instantly share code, notes, and snippets.

@ForbesLindesay
Created April 8, 2013 00:20
Show Gist options
  • Select an option

  • Save ForbesLindesay/5333257 to your computer and use it in GitHub Desktop.

Select an option

Save ForbesLindesay/5333257 to your computer and use it in GitHub Desktop.
var request = require('request');
module.exports = dropbox;
function dropbox(consumerKey, consumerSecret, accessToken, accessTokenSecret) {
var errors = {
'304': 'The folder contents have not changed'
, '400': 'The extension is on Dropbox\'s ignore list.'
, '403': 'An invalid copy operation was attempted (e.g. there is already a file at the given destination, or copying a shared folder into a shared folder).'
, '404': 'The requested file or revision was not found.'
, '406': 'There are too many file entries to return.'
, '411': 'Chunked encoding was attempted for this upload, but is not supported by Dropbox.'
, '415': 'The image is invalid and cannot be converted to a thumbnail.'
};
function method(method) {
function doRequest(path, query, body, callback) {
if (typeof body === 'function') callback = body, body = undefined;
var oauth = {
consumer_key: consumerKey
, consumer_secret: consumerSecret
, token: accessToken
, token_secret: accessTokenSecret
};
var requestOptions = { uri: 'https://api.dropbox.com/1' + path.split(/\//).map(encodeURIComponent).join('/'), oauth: oauth };
if (body) {
if (method === 'get') {
requestOptions.headers = { Range: body };
} else {
requestOptions.form = body;
}
}
if (query) {
requestOptions.qs = query;
}
return request[method](requestOptions, callback ?
function(err, res, body) {
if (err) return callback(err);
var contentType = res.headers['content-type'];
// check if the response body is in JSON format
try {
body = JSON.parse(body);
} catch (ex) {
//assume not a json response
}
if (body.error) {
var err = new Error(typeof body.error === 'string' ? body.error : JSON.stringify(body.error));
err.statusCode = res.statusCode;
return callback(err);
}
if (errors[res.statusCode]) {
var err = new Error(errors[res.statusCode]);
err.statusCode = res.statusCode;
return callback(err);
}
// check for metadata in headers
if (res.headers['x-dropbox-metadata']) {
var metadata = JSON.parse(res.headers['x-dropbox-metadata']);
}
callback(null, body, metadata || {});
} : undefined);
}
return retry(doRequest);
}
return {
get: method('get'),
post: method('post'),
put: method('put'),
delete: method('delete'),
head: method('head')
};
}
function retry(fn) {
return function () {
var args = arguments;
var attempt = 0;
for (var i = 0; i < args.length; i++) {
if (typeof args[i] === 'function') {
args[i] = (function (cb) {
return function (err) {
if (err && attempt < 10) {
attempt++;
console.warn('retrying: ' + attempt);
return setTimeout(function () { fn.apply(this, args); }, 4000 * attempt * attempt);
} else {
return cb.apply(this, arguments);
}
}
}(args[i]));
}
}
return fn.apply(this, args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment