<commit_before>'use strict';

/**
 * Module to interact with Asana tasks.
 * @module asana/task
 */

 
var conf = require("../conf"),
  helper = require("./helper"),
  item = require("../item"),
  parser = require("../parser"),
  _ = require("lodash"),
  request = require("superagent"),
  P = require("bluebird"),
  apiUrl = "https://app.asana.com/api/1.0/";

require("superagent-bluebird-promise");
require("string.prototype.endswith");


/**
 * Create an Item from an Asana task.
 * @param {asana:Task} task - Task as returned by Asana API.
 * @returns {item:Item}
 *
 * @private
 * @static
 */
function toItem (task) {
  var it = item.create({
    "title" : task.name,
    "managerId" : task.id.toString(),
    "completed" : task.completed,
    "lastUpdated" : Date.parse(task["modified_at"])
  });
  
  // TODO check if task is in 2 or more projects with CC prefix --> Warn
  
  it.body = parser.extractFields(task.notes, it.fields);
  it.tags = task.tags.map(function (tag) {
    return tag.name;
  });
  
  return it;
}


/**
 * Create an Asana task from an ITem
 * @param {item:Item} item
 * @returns {asana:Task} task - Task ready to be send to Asana service.
 *
 * @private
 * @static
 */
function fromItem (item) {
  var task = {
      data : {
        name : item.title,
        notes : item.body,
        completed : item.completed
      }
    }, 
    fieldsAsString = parser.serializeFields(item.fields);
  
  // Append fields to notes
  if (fieldsAsString.length > 0) {
    // Insert 2 blank lines if needed
    if (!task.data.notes.endsWith("\n\n")) {
      task.data.notes += task.data.notes.endsWith("\n") ? "\n" : "\n\n";
    }
    task.data.notes += fieldsAsString;
  }
  
  return task;
}


/**
 * Get an array of Asana tasks
 * @param {asana:Project} project - A Project as returned by the Asana API.
 * @returns {Array.<asana:Task>} - Array of Task as returned by Asana API.
 *
 * @private
 * @static
 */
function getTasks (project) {
  return request
    .get(apiUrl + "tasks")
    .query({"project": project.id})
    .query({"opt_fields": "id,name,notes,modified_at,completed,assignee.name,assignee.email,tags.name,projects.name"})
    .auth(helper.getUser(), helper.getPsw())
    .promise()
    .then(function (res) {
      return res.body.data;
    });
}


/**
 * Get an array of Items from Asana.
 * @param {asana:Project} project - A Project as returned by the Asana API.
 * @returns {Array.<item:Item>}
 *
 * @static
 */
function getItems (project) {
  return getTasks(project).map(function (task) {
    var item = toItem(task);
    
    // Include any extracted fields from project
    // If field already exists, it is overwritten.
    // This could avoid some errors when creating new tasks in asana
    // For example if create a task with an #owner field different than the #owner specified in the project
    _.assign(item.fields, project.fields);
    
    return item;
  });
}

<commit_msg>Fix #12 Handle empty asana tasks<commit_after>'use strict';

/**
 * Module to interact with Asana tasks.
 * @module asana/task
 */

 
var conf = require("../conf"),
  helper = require("./helper"),
  item = require("../item"),
  parser = require("../parser"),
  _ = require("lodash"),
  request = require("superagent"),
  P = require("bluebird"),
  apiUrl = "https://app.asana.com/api/1.0/";

require("superagent-bluebird-promise");
require("string.prototype.endswith");


/**
 * Create an Item from an Asana task.
 * @param {asana:Task} task - Task as returned by Asana API.
 * @returns {item:Item}
 *
 * @private
 * @static
 */
function toItem (task) {
  var it = item.create({
    "title" : task.name,
    "managerId" : task.id.toString(),
    "completed" : task.completed,
    "lastUpdated" : Date.parse(task["modified_at"])
  });
  
  // TODO check if task is in 2 or more projects with CC prefix --> Warn
  
  it.body = parser.extractFields(task.notes, it.fields);
  it.tags = task.tags.map(function (tag) {
    return tag.name;
  });
  
  return it;
}


/**
 * Create an Asana task from an ITem
 * @param {item:Item} item
 * @returns {asana:Task} task - Task ready to be send to Asana service.
 *
 * @private
 * @static
 */
function fromItem (item) {
  var task = {
      data : {
        name : item.title,
        notes : item.body,
        completed : item.completed
      }
    }, 
    fieldsAsString = parser.serializeFields(item.fields);
  
  // Append fields to notes
  if (fieldsAsString.length > 0) {
    // Insert 2 blank lines if needed
    if (!task.data.notes.endsWith("\n\n")) {
      task.data.notes += task.data.notes.endsWith("\n") ? "\n" : "\n\n";
    }
    task.data.notes += fieldsAsString;
  }
  
  return task;
}


/**
 * Get an array of Asana tasks
 * @param {asana:Project} project - A Project as returned by the Asana API.
 * @returns {Array.<asana:Task>} - Array of Task as returned by Asana API. Tasks
 *    with empty names are excluded
 *
 * @private
 * @static
 */
function getTasks (project) {
  return request
    .get(apiUrl + "tasks")
    .query({"project": project.id})
    .query({"opt_fields": "id,name,notes,modified_at,completed,assignee.name,assignee.email,tags.name,projects.name"})
    .auth(helper.getUser(), helper.getPsw())
    .promise()
    .then(function (res) {
      return res.body.data.filter(function (task) {
        return task.name.trim().length > 0;
      });
    });
}


/**
 * Get an array of Items from Asana.
 * @param {asana:Project} project - A Project as returned by the Asana API.
 * @returns {Array.<item:Item>}
 *
 * @static
 */
function getItems (project) {
  return getTasks(project).map(function (task) {
    var item = toItem(task);
    
    // Include any extracted fields from project
    // If field already exists, it is overwritten.
    // This could avoid some errors when creating new tasks in asana
    // For example if create a task with an #owner field different than the #owner specified in the project
    _.assign(item.fields, project.fields);
    
    return item;
  });
}


{'fraction_non_alphanumeric': 0.1505089270815952, 'fraction_numerical': 0.0021691973969631237, 'mean_word_length': 2.8771021992238035, 'pattern_counts': {'":': 4, '<': 7, '<?xml version=': 0, '>': 12, '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': '4355970', 'n_tokens_mistral': 1969, 'n_tokens_neox': 1925, 'n_words': 553}