bcongdon/WunderSchedule

View on GitHub
utils/parseTaskTemplate.js

Summary

Maintainability
B
6 hrs
Test Coverage
'use strict';
/*
    parseTaskTemplate

    Handles parsing of task 'templates' as defined in the tasks of the
    scheduled list.
*/

var note = require('./note.js');
var task = require('./task.js');
var parseDate = require('./parseDate');
var log = require('./logging.js').log;
require('datejs');

var exports = module.exports;

var start_time_strings = ['start-time:',
                          's:',
                          'start:'];

var due_date_strings = ['due-date:',
                        'due:',
                        'd:'];

var repeat_every_strings = ['repeat-every:',
                            'repeat:',
                            'r:'];

var starred_strings = ['starred',
                       'star'];

var note_strings = ['note:',
                    'n:'];

var list_strings = ['list:',
                    'l:'];

var reminder_strings = ['reminder:',
                        'remind:',
                        'rem:'];


// Line starts with one of the strings in strings
exports.startsWithOneOf = function(line, strings){
  var retVal = false;
  strings.forEach(function(prefix){
    if(line.toLowerCase().trim().indexOf(prefix) === 0){
      retVal = true;
    }
  });
  return retVal;
};

// Removes prefix and following whitespace from str
exports.removePrefix = function (str) {
  var re = new RegExp(/^[^:]*:\s*/);
  var match = str.replace(re,'');
  return match;
};

// Parses the 'note' of a template tasks. Extracts keywords like 'start-time',
// etc. and returns a dictionary.
exports.parseContentString = function(str) {
  'use strict';
  var template_dict = {};
  var lines = str.split(/[\n\r;]+/);
  var i = 0, dateStr = '';
  for (i = 0; i < lines.length; i += 1) {
    if (exports.startsWithOneOf(lines[i], start_time_strings)) {
      template_dict.start_time_str = exports.removePrefix(lines[i]);
    } else if (exports.startsWithOneOf(lines[i], due_date_strings)) {
      dateStr = exports.removePrefix(lines[i]);
      template_dict.due_date = parseDate.parseDateString(dateStr);
    } else if (exports.startsWithOneOf(lines[i], starred_strings)) {
      template_dict.starred = true;
    } else if (exports.startsWithOneOf(lines[i], repeat_every_strings)) {
      template_dict.repeat_every = exports.removePrefix(lines[i]);
    } else if (exports.startsWithOneOf(lines[i], note_strings)) {
      template_dict.note = exports.removePrefix(lines[i]);
    } else if (exports.startsWithOneOf(lines[i], list_strings)) {
      template_dict.list = exports.removePrefix(lines[i]);
    } else if (exports.startsWithOneOf(lines[i], reminder_strings)){
      template_dict.reminder_str = exports.removePrefix(lines[i]);
    }
  }

    // If no due date specified, default to today
  if(!template_dict.due_date){
    template_dict.due_date = parseDate.parseDateString('today at 12pm');
  }
    
    // Assume start time is on due date
  if(template_dict.start_time_str) {
    template_dict.start_time = Date.parse(template_dict.due_date.toString('yyyy/MM/dd') + ' ' + template_dict.start_time_str);
  }

    // Assume reminder time is on due date
  if(template_dict.reminder_str) {
    template_dict.reminder = new Date.parse(template_dict.due_date.toString('yyyy/MM/dd') + ' ' + template_dict.reminder_str);
  }

  return template_dict;
};

exports.templateToNoteString = function (template) {
  var contentStr = '';
  if (template.repeat_every) contentStr += 'repeat-every: ' + template.repeat_every + '\n';
  if (template.starred) contentStr += 'starred\n';
  if (template.list) contentStr += 'list: ' + template.list + '\n';
  if (template.note) contentStr += 'note: ' + template.note + '\n';
  if (template.due_date) contentStr += 'due-date: ' + template.due_date.toString('yyyy/MM/dd') + '\n';
  if (template.start_time) contentStr += 'start-time: ' + new Date(template.start_time).toString('hh:mm tt') + '\n';
  if (template.reminder) contentStr += 'reminder: ' + new Date(template.reminder).toString('hh:mm tt') + '\n';
    
  return contentStr;
};

// Takes a template dictionary and uses it to update the task that it came
// from. (i.e. Once a repeating task has run to update next start
// date)
exports.pushTemplateUpdate = function (template) {
  var template_string = exports.templateToNoteString(template);
  note.updateNoteContent(template_string, template.task_id);
};


exports.updateTemplateWithRepeat = function (task_template){
  'use strict';
  var rep_str = task_template.repeat_every;
  if (rep_str) {
    var old_due_time = task_template.due_date;
        //Split by comma, remove whitespace
    var rep_args = rep_str.split(',');
    var i = 0; 
    var rep_dates = [];
    var currDate;
    for (i = 0; i < rep_args.length; i += 1){
      currDate = parseDate.parseRepetitionToDates(rep_args[i]);
      if(currDate.toString().length > 15) rep_dates.push(currDate);
    }

        // Sorts repetition dates in 'ascending' order
    rep_dates.sort(function(a,b){
      return a - b;
    });

        // No 'earliest' date
    if(!rep_dates[0]) {
      task.logTask(task_template.task_id, 'Couldn\'t parse repeat for task template.', 'warn');
      return null;
    }
    task_template.due_date = rep_dates[0];
    if(old_due_time){
      task_template.due_date = new Date.parse(
                task_template.due_date.toString('yyyy/MM/dd') + ' ' +
                old_due_time.toString('hh:mm tt')
            );
    }
    return task_template;
  }
  task.getTask(task_template.task_id, function(task){
    log.error('Template with name \'' + task.title + '\' does not have a repetition defined.');
  });
  return null;
};

// Extracts templates from a given list. Tries to extract template dict from
// each task in list, and calls back with a list of template dictionaries.
exports.extractTemplateTasks = function (list_id, cb) {
  'use strict';
  note.getNoteList(list_id, function (res_body) {
    var templates = [], new_template = '';
    var i = 0;
    var warn = function(task){
      log.warn('Task with name \'' + task.title + '\' has no start time!');
    };
    for (i = 0; i < res_body.length; i += 1) {
            
      if (res_body[i].content) {
        new_template = exports.parseContentString(res_body[i].content);
        new_template.task_id = res_body[i].task_id;
        if(!('start_time' in new_template)){
          task.getTask(new_template.task_id, warn);
        }
        templates.push(new_template);
      }
    }
    cb(templates);
  });
};