orgdo
Version:
Command-line tool to manage the Todo lists
111 lines (110 loc) • 3.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const timestring = require("timestring");
const os = require("os");
const RE_TIME = /^\d{2,4}-\d{2}-\d{2}( \d{2}:\d{2}(:\d{2})?)?$/;
class Task {
static create(data) {
const task = new Task(data.id, data.name);
task.tags = data.tags ? formatTags(data.tags) : [];
task.update(data);
return task;
}
static sort(t1, t2) {
const p1 = priorityToInt(t1.priority);
const p2 = priorityToInt(t2.priority);
if (p1 === p2) {
return t1.id - t2.id;
}
else {
return p2 - p1;
}
}
static fromJSON(data) {
["start", "started", "complete", "completed"].forEach(key => {
if (data[key]) {
data[key] = new Date(data[key]);
}
});
const task = Object.assign(new Task(data.id, data.name), data);
return task;
}
constructor(id, name) {
this.id = id;
this.name = _.trim(_.replace(name, os.EOL, " "));
this.status = "todo";
this.priority = "medium";
}
addTags(tags) {
const normalizedTags = formatTags(tags);
this.tags = _.union(this.tags, normalizedTags);
return this;
}
removeTags(tags) {
const normalizedTags = formatTags(tags);
_.remove(this.tags, v => normalizedTags.indexOf(v) !== -1);
return this;
}
update(data) {
if (data.name) {
this.name = data.name;
}
if (data.describe) {
this.describe = data.describe;
}
if (data.priority) {
this.priority = data.priority;
}
if (data.start) {
this.start = parseTimestr(data.start);
}
if (data.complete) {
this.complete = parseTimestr(data.complete);
}
return this;
}
updateStatus(status) {
if (this.status === "done" || this.status === "canceled") {
throw new Error("Cannot update finished task");
}
this.status = status;
}
}
exports.default = Task;
function formatTags(tags) {
return _.flatMap(tags.map(tag => tag.split(",")));
}
function parseTimestr(timestr) {
timestr = _.trim(timestr);
const createErr = () => new Error("Invalid timestr");
let date;
if (RE_TIME.test(timestr)) {
if (/^\d{2}-/.test(timestr)) {
timestr = "20" + timestr;
}
date = new Date(timestr);
if (!/\d{2}:\d{2}(:\d{2})?$/.test(timestr)) {
date.setHours(0);
}
if (isNaN(date)) {
throw createErr();
}
return date;
}
const time = timestring(timestr, "ms");
if (time === 0) {
throw createErr();
}
return new Date(Date.now() + time);
}
function priorityToInt(priority) {
switch (priority) {
case "high":
return 1;
case "low":
return -1;
default:
return 0;
}
}