<commit_before>var unirest = require('unirest');
var Settings = require('../helper/Settings');
var XMLHttpRequest = require('xhr2');

var Dropbox = {};

Dropbox.init = function (){
  this.USERTOKEN = Settings.get('dropbox_token');
};

Dropbox._handleJson = function (xmlhttp, cb){
  if(xmlhttp.readyState !== 4)
    return ;

  var response = {
    data: null
  };
  if (xmlhttp.status == 200) {
    try {
      response.data = JSON.parse(xmlhttp.responseText);
      cb(null, response);
    } catch (e) {
      cb({
        error: 'parsing failed.'
      }, response);
    }
  } else if (xmlhttp.status == 404){
    cb(null, response); // File not found
  } else {
    cb({
      error: 'http status: ' + xmlhttp.status
    }, response);
  }
};

Dropbox.quota = function (cb){
  var self = this;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('get', 'https://api.dropbox.com/1/account/info', true);
  xmlhttp.setRequestHeader('Authorization', 'Bearer ' + self.USERTOKEN);
  xmlhttp.setRequestHeader('Accept', 'application/json');
  xmlhttp.onreadystatechange = function () {
    self._handleJson(xmlhttp, function (error, response){
      if (response.data) {
        var quotaInfo = response.data.quota_info;
        var result = {
          data:{
            quota: quotaInfo.quota,
            used: (quotaInfo.normal + quotaInfo.shared)
          }
        };
        cb(error, result);
      } else {
        cb(error, response);
      }
    });
  };

  xmlhttp.send();
};

Dropbox._convertItem = function (data){
  return {
    isdir: data.is_dir ? 1 : 0,
    path: data.path,
    size: data.bytes,
    // Date format:
    // "%a, %d %b %Y %H:%M:%S %z"
    //
    // Example: "Sat, 21 Aug 2010 22:31:20 +0000"
    mtime: new Date(data.modified).getTime(),
    ctime: new Date(data.modified).getTime()
  };
};

Dropbox.getFileMeta = function (path, cb){
  var self = this;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('get', 'https://api.dropbox.com/1/metadata/auto' + path, true);
  xmlhttp.setRequestHeader('Authorization', 'Bearer ' + self.USERTOKEN);
  xmlhttp.setRequestHeader('Accept', 'application/json');
  xmlhttp.onreadystatechange = function () {
    self._handleJson(xmlhttp, function (error, response){
      if (response.data) {
        var data = response.data;
        var result = {
          data:{
            list: [self._convertItem(data)]
          }
        };
        cb(error, result);
      } else {
        cb(error, response);
      }
    });
  };

  xmlhttp.send('list=false');
};

Dropbox.getFileList = function (path, cb){
  var self = this;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('get', 'https://api.dropbox.com/1/metadata/auto' + path, true);
  xmlhttp.setRequestHeader('Authorization', 'Bearer ' + self.USERTOKEN);
  xmlhttp.setRequestHeader('Accept', 'application/json');
  xmlhttp.onreadystatechange = function () {
    self._handleJson(xmlhttp, function (error, response){
      if (response.data) {
        var data = response.data;
        var resultList = [];
        for(var i = 0; i < data.contents.length; i++){
          var content = data.contents[i];
          resultList.push(self._convertItem(content));
        }
        var result = {
          data:{
            list: resultList
          }
        };
        cb(error, result);
      } else {
        cb(error, response);
      }
    });
  };

  xmlhttp.send('list=true');
};

Dropbox.getFileDownload = function (path, offset, size, cb){
  var self = this;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('get', 'https://api-content.dropbox.com/1/files/auto' + path, true);
  xmlhttp.setRequestHeader('Authorization', 'Bearer ' + self.USERTOKEN);
  xmlhttp.setRequestHeader('Range', 'bytes=' + offset + '-' + ( offset + size - 1 ));
  xmlhttp.responseType = 'buffer';
  xmlhttp.onload = function () {
    var res = xmlhttp.response;
    var length = res.length;
    cb(null, {
      data: res,
      length: length
    });
  };

  xmlhttp.send();
};

Dropbox._tokenRequest = function (link, auth, params, cb){
  var self = this;
  unirest.post(link)
  .auth(auth)
  .header('Accept', 'application/json')
  .send(params)
  .end(function (httpResponse) {
    self._handleJson(httpResponse, cb);
  });
};

/*
step 1: Dropbox.getAuthLink
Visit the link: https://www.dropbox.com/1/oauth2/authorize?
client_id=<API_KEY>&
response_type=code
*/

Dropbox.getAuthLink = function (api_key, cb){
  var link = 'https://www.dropbox.com/1/oauth2/authorize?' +
    'client_id=' + api_key + '&' +
    'response_type=code';
  cb(null, {data: {
    authLink: link
  }});
};

/*
step 2: Dropbox.getAccessToken
curl https://api.dropbox.com/1/oauth2/token \
-d code=<USER_CODE> \
-d grant_type=authorization_code \
-u <API_KEY>:<API_SECRET>

Response:
{
  "access_token": "<ACCESS_TOKEN>",
  "token_type": "bearer",
  "uid": "??????"
}
*/
Dropbox.getAccessToken = function (api_key, api_secret, device_code, cb){
  var linkToken = 'https://api.dropbox.com/1/oauth2/token';
  this._tokenRequest(linkToken, {
    'user': api_key,
    'pass': api_secret
  }, {
    'code': device_code,
    'grant_type': 'authorization_code'
  }, cb);
};

module.exports = Dropbox;
<commit_msg>Use load event instead of readystatechange.<commit_after>var unirest = require('unirest');
var Settings = require('../helper/Settings');
var XMLHttpRequest = require('xhr2');

var Dropbox = {};

Dropbox.init = function (){
  this.USERTOKEN = Settings.get('dropbox_token');
};

Dropbox._handleJson = function (xmlhttp, cb){
  var response = {
    data: null
  };
  if (xmlhttp.status == 200) {
    try {
      response.data = JSON.parse(xmlhttp.responseText);
      cb(null, response);
    } catch (e) {
      cb({
        error: 'parsing failed.'
      }, response);
    }
  } else if (xmlhttp.status == 404){
    cb(null, response); // File not found
  } else {
    cb({
      error: 'http status: ' + xmlhttp.status
    }, response);
  }
};

Dropbox.quota = function (cb){
  var self = this;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('get', 'https://api.dropbox.com/1/account/info', true);
  xmlhttp.setRequestHeader('Authorization', 'Bearer ' + self.USERTOKEN);
  xmlhttp.setRequestHeader('Accept', 'application/json');
  xmlhttp.onload = function () {
    self._handleJson(xmlhttp, function (error, response){
      if (response.data) {
        var quotaInfo = response.data.quota_info;
        var result = {
          data:{
            quota: quotaInfo.quota,
            used: (quotaInfo.normal + quotaInfo.shared)
          }
        };
        cb(error, result);
      } else {
        cb(error, response);
      }
    });
  };

  xmlhttp.send();
};

Dropbox._convertItem = function (data){
  return {
    isdir: data.is_dir ? 1 : 0,
    path: data.path,
    size: data.bytes,
    // Date format:
    // "%a, %d %b %Y %H:%M:%S %z"
    //
    // Example: "Sat, 21 Aug 2010 22:31:20 +0000"
    mtime: new Date(data.modified).getTime(),
    ctime: new Date(data.modified).getTime()
  };
};

Dropbox.getFileMeta = function (path, cb){
  var self = this;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('get', 'https://api.dropbox.com/1/metadata/auto' + path, true);
  xmlhttp.setRequestHeader('Authorization', 'Bearer ' + self.USERTOKEN);
  xmlhttp.setRequestHeader('Accept', 'application/json');
  xmlhttp.onload = function () {
    self._handleJson(xmlhttp, function (error, response){
      if (response.data) {
        var data = response.data;
        var result = {
          data:{
            list: [self._convertItem(data)]
          }
        };
        cb(error, result);
      } else {
        cb(error, response);
      }
    });
  };

  xmlhttp.send('list=false');
};

Dropbox.getFileList = function (path, cb){
  var self = this;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('get', 'https://api.dropbox.com/1/metadata/auto' + path, true);
  xmlhttp.setRequestHeader('Authorization', 'Bearer ' + self.USERTOKEN);
  xmlhttp.setRequestHeader('Accept', 'application/json');
  xmlhttp.onload = function () {
    self._handleJson(xmlhttp, function (error, response){
      if (response.data) {
        var data = response.data;
        var resultList = [];
        for(var i = 0; i < data.contents.length; i++){
          var content = data.contents[i];
          resultList.push(self._convertItem(content));
        }
        var result = {
          data:{
            list: resultList
          }
        };
        cb(error, result);
      } else {
        cb(error, response);
      }
    });
  };

  xmlhttp.send('list=true');
};

Dropbox.getFileDownload = function (path, offset, size, cb){
  var self = this;
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.open('get', 'https://api-content.dropbox.com/1/files/auto' + path, true);
  xmlhttp.setRequestHeader('Authorization', 'Bearer ' + self.USERTOKEN);
  xmlhttp.setRequestHeader('Range', 'bytes=' + offset + '-' + ( offset + size - 1 ));
  xmlhttp.responseType = 'buffer';
  xmlhttp.onload = function () {
    var res = xmlhttp.response;
    var length = res.length;
    cb(null, {
      data: res,
      length: length
    });
  };

  xmlhttp.send();
};

Dropbox._tokenRequest = function (link, auth, params, cb){
  var self = this;
  unirest.post(link)
  .auth(auth)
  .header('Accept', 'application/json')
  .send(params)
  .end(function (httpResponse) {
    self._handleJson(httpResponse, cb);
  });
};

/*
step 1: Dropbox.getAuthLink
Visit the link: https://www.dropbox.com/1/oauth2/authorize?
client_id=<API_KEY>&
response_type=code
*/

Dropbox.getAuthLink = function (api_key, cb){
  var link = 'https://www.dropbox.com/1/oauth2/authorize?' +
    'client_id=' + api_key + '&' +
    'response_type=code';
  cb(null, {data: {
    authLink: link
  }});
};

/*
step 2: Dropbox.getAccessToken
curl https://api.dropbox.com/1/oauth2/token \
-d code=<USER_CODE> \
-d grant_type=authorization_code \
-u <API_KEY>:<API_SECRET>

Response:
{
  "access_token": "<ACCESS_TOKEN>",
  "token_type": "bearer",
  "uid": "??????"
}
*/
Dropbox.getAccessToken = function (api_key, api_secret, device_code, cb){
  var linkToken = 'https://api.dropbox.com/1/oauth2/token';
  this._tokenRequest(linkToken, {
    'user': api_key,
    'pass': api_secret
  }, {
    'code': device_code,
    'grant_type': 'authorization_code'
  }, cb);
};

module.exports = Dropbox;

{'fraction_non_alphanumeric': 0.16461940226327498, 'fraction_numerical': 0.00802785569203985, 'mean_word_length': 2.855331841909023, 'pattern_counts': {'":': 6, '<': 15, '<?xml version=': 0, '>': 13, 'https://': 16, 'lorem ipsum': 0, 'www.': 4, 'xml': 69}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5142031', 'n_tokens_mistral': 3570, 'n_tokens_neox': 3513, 'n_words': 702}