<commit_before>/** @jsx React.DOM */
/* global gapi */

var Cache = require('./Cache.js');
var _ = require('lodash');

var messageCache = new Cache('messages');
var isAvailable = false;
var pendingRequests = [];

window.handleGoogleClientLoad = function() {
  var config = {
    client_id: '108971935462-ied7vg89qivj0bsso4imp6imhvpuso5u.apps.googleusercontent.com',
    scope: 'email https://mail.google.com',
    immediate: true
  };
  gapi.auth.authorize(config, whenAuthenticated);
};

function whenAuthenticated() {
  gapi.client.load('gmail', 'v1', whenLoaded);
}

function whenLoaded() {
  isAvailable = true;
  if (pendingRequests.length) {
    pendingRequests.forEach(request => request());
  }
  pendingRequests = [];
}

function whenGoogleApiAvailable(fn) {
  if (isAvailable) {
    fn();
  } else {
    pendingRequests.push(fn);
  }
}

function transformMessage(rawMessage) {
  var msg = rawMessage.payload;
  return {
    body: decodeBody(rawMessage),
    from: parseFrom(pluckHeader(msg.headers, 'From')),
    id: rawMessage.id,
    raw: rawMessage,
    snippet: rawMessage.snippet,
    subject: pluckHeader(msg.headers, 'Subject'),
  };
}

function parseFrom(from) {
  var i = from.indexOf('<');
  return {
    // remove surrounding quotes from name
    name: from.substring(0, i).trim().replace(/(^")|("$)/g, ''),
    email: from.substring(i + 1, from.length - 1)
  };
}

function decodeBody(rawMessage) {
  var parts = (rawMessage.payload.parts || []).concat(rawMessage.payload);
  var result = {};

  parts.forEach(part => {
    if (part.body.data) {
      var contentTypeHeader = pluckHeader(part.headers, 'Content-Type');
      var contentType = contentTypeHeader ?
        contentTypeHeader.split(';')[0] :
        'text/html';
      result[contentType] =
        decodeUrlSafeBase64(part.body.data);
    }
  });

  return result;
}

function decodeUrlSafeBase64(s) {
  return atob(s.replace(/\-/g, '+').replace(/\_/g, '/'));
}

function pluckHeader(headers, name) {
  var header = headers.filter(h => h.name === name)[0];
  return header ? header.value : null;
}

module.exports.getMessages = function(options, callback) {
  whenGoogleApiAvailable(() => {
    var request = gapi.client.gmail.users.messages.list({
      userID: 'me',
      maxResults: 100,
      q: options.query || null
    });

    request.execute(response => {
      var messageIDs = response.messages.map(m => m.id);
      var cachedMessagesByID = {};
      var batch;

      messageIDs.forEach(id => {
        var cachedMessage = messageCache.get(id);
        if (cachedMessage) {
          cachedMessagesByID[id] = cachedMessage;
          return;
        }<commit_msg>Add hasAttachment to translated message<commit_after>/** @jsx React.DOM */
/* global gapi */

var Cache = require('./Cache.js');
var _ = require('lodash');

var messageCache = new Cache('messages');
var isAvailable = false;
var pendingRequests = [];

window.handleGoogleClientLoad = function() {
  var config = {
    client_id: '108971935462-ied7vg89qivj0bsso4imp6imhvpuso5u.apps.googleusercontent.com',
    scope: 'email https://mail.google.com',
    immediate: true
  };
  gapi.auth.authorize(config, whenAuthenticated);
};

function whenAuthenticated() {
  gapi.client.load('gmail', 'v1', whenLoaded);
}

function whenLoaded() {
  isAvailable = true;
  if (pendingRequests.length) {
    pendingRequests.forEach(request => request());
  }
  pendingRequests = [];
}

function whenGoogleApiAvailable(fn) {
  if (isAvailable) {
    fn();
  } else {
    pendingRequests.push(fn);
  }
}

function transformMessage(rawMessage) {
  var msg = rawMessage.payload;
  return {
    body: decodeBody(rawMessage),
    from: parseFrom(pluckHeader(msg.headers, 'From')),
    id: rawMessage.id,
    raw: rawMessage,
    snippet: rawMessage.snippet,
    subject: pluckHeader(msg.headers, 'Subject'),
    hasAttachment: !!msg.body.data,
  };
}

function parseFrom(from) {
  var i = from.indexOf('<');
  return {
    // remove surrounding quotes from name
    name: from.substring(0, i).trim().replace(/(^")|("$)/g, ''),
    email: from.substring(i + 1, from.length - 1)
  };
}

function decodeBody(rawMessage) {
  var parts = (rawMessage.payload.parts || []).concat(rawMessage.payload);
  var result = {};

  parts.forEach(part => {
    if (part.body.data) {
      var contentTypeHeader = pluckHeader(part.headers, 'Content-Type');
      var contentType = contentTypeHeader ?
        contentTypeHeader.split(';')[0] :
        'text/html';
      result[contentType] =
        decodeUrlSafeBase64(part.body.data);
    }
  });

  return result;
}

function decodeUrlSafeBase64(s) {
  return atob(s.replace(/\-/g, '+').replace(/\_/g, '/'));
}

function pluckHeader(headers, name) {
  var header = headers && headers.filter(h => h.name === name)[0];
  return header ? header.value : null;
}

module.exports.getMessages = function(options, callback) {
  whenGoogleApiAvailable(() => {
    var request = gapi.client.gmail.users.messages.list({
      userID: 'me',
      maxResults: 100,
      q: options.query || null
    });

    request.execute(response => {
      var messageIDs = response.messages.map(m => m.id);
      var cachedMessagesByID = {};
      var batch;

      messageIDs.forEach(id => {
        var cachedMessage = messageCache.get(id);
        if (cachedMessage) {
          cachedMessagesByID[id] = cachedMessage;
          return;
        }
{'fraction_non_alphanumeric': 0.15447305056491942, 'fraction_numerical': 0.011854047045749213, 'mean_word_length': 3.3654001616814875, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3640403', 'n_tokens_mistral': 1772, 'n_tokens_neox': 1736, 'n_words': 337}