Skip to content

Commit

Permalink
choose a random task
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianHicks committed Oct 14, 2022
1 parent 4544efa commit 632bc3f
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 2 deletions.
1 change: 1 addition & 0 deletions Gardening.omnifocusjs/Resources/en.lproj/manifest.strings
@@ -0,0 +1 @@
"zone.bytes.gardening" = "Digital Gardening for Omnifocus";
5 changes: 5 additions & 0 deletions Gardening.omnifocusjs/Resources/en.lproj/pick.strings
@@ -0,0 +1,5 @@
"label" = "Pick Something";
"shortLabel" = "Pick";
"mediumLabel" = "Pick Something";
"longLabel" = "Pick Something";
"paletteLabel" = "Pick";
88 changes: 88 additions & 0 deletions Gardening.omnifocusjs/Resources/pick.js
@@ -0,0 +1,88 @@
"use strict";
(() => {
let creds = new Credentials();
var getWeights = function () {
const now = new Date();
const hour = now.getHours();
const day = now.getDay();
if (hour >= 8 && hour <= 17 && day != 0 && day != 6) {
return { work: 0.8, personal: 0.2 };
}
else {
return { work: 0.8, personal: 0.2 };
return { work: 0.0, personal: 1.0 };
}
};
var categorizeTask = function (task) {
var todo = task.tags;
while (todo.length != 0) {
let tag = todo.pop();
if (tag.name == "work") {
return "work";
}
else if (tag.name == "personal") {
return "personal";
}
else if (tag.parent) {
todo.push(tag.parent);
}
}
return null;
};
var daysBetween = function (a, b) {
let millis = Math.abs(a.getTime() - b.getTime());
return millis / 1000 / 60 / 60 / 24;
};
var weightedRandom = function (pairs) {
var total = 0;
for (let pair of pairs) {
total += pair[1];
}
let target = Math.random() * total;
for (let pair of pairs) {
target -= pair[1];
if (target <= 0) {
return pair[0];
}
}
return null;
};
var chooseATask = function () {
let weights = getWeights();
let now = new Date();
let possibleTasks = flattenedProjects
.filter((p) => p.status == Project.Status.Active)
.flatMap((p) => p.flattenedTasks.filter((t) => t.taskStatus == Task.Status.Available ||
t.taskStatus == Task.Status.DueSoon ||
t.taskStatus == Task.Status.Next ||
t.taskStatus == Task.Status.Overdue));
let weightedTasks = [];
for (let task of possibleTasks) {
// weight some categories higher than others
let categoryWeight = 0;
let category = categorizeTask(task);
if (category) {
categoryWeight = weights[category];
}
// weight stale-er tasks higher, up to 7 days
let ageWeight = Math.min(7, daysBetween(now, task.modified)) / 7;
// weight due-er tasks higher, up to 100 points
let dueWeight = 0;
if (task.effectiveDueDate) {
dueWeight = 100 - daysBetween(now, task.effectiveDueDate);
}
weightedTasks.push([task, ageWeight + dueWeight + categoryWeight]);
}
return weightedRandom(weightedTasks);
};
var action = new PlugIn.Action(async () => {
try {
console.log(`task: ${chooseATask()}`);
}
catch (err) {
console.error(err);
throw err;
}
});
return action;
})();
Binary file added Gardening.omnifocusjs/Resources/pick.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 108 additions & 0 deletions Gardening.omnifocusjs/Resources/pick.ts
@@ -0,0 +1,108 @@
(() => {
let creds = new Credentials();

var getWeights = function (): { work: number; personal: number } {
const now = new Date();
const hour = now.getHours();
const day = now.getDay();

if (hour >= 8 && hour <= 17 && day != 0 && day != 6) {
return { work: 0.8, personal: 0.2 };
} else {
return { work: 0.8, personal: 0.2 };
return { work: 0.0, personal: 1.0 };
}
};

var categorizeTask = function (task: Task): "work" | "personal" | null {
var todo = task.tags;
while (todo.length != 0) {
let tag = todo.pop();

if (tag.name == "work") {
return "work";
} else if (tag.name == "personal") {
return "personal";
} else if (tag.parent) {
todo.push(tag.parent);
}
}

return null;
};

var daysBetween = function (a: Date, b: Date): number {
let millis = Math.abs(a.getTime() - b.getTime());
return millis / 1000 / 60 / 60 / 24;
};

var weightedRandom = function <Type>(pairs: [Type, number][]): Type | null {
var total = 0;
for (let pair of pairs) {
total += pair[1];
}

let target = Math.random() * total;
for (let pair of pairs) {
target -= pair[1];

if (target <= 0) {
return pair[0];
}
}

return null;
};

var chooseATask = function (): Task | null {
let weights = getWeights();
let now = new Date();

let possibleTasks = flattenedProjects
.filter((p) => p.status == Project.Status.Active)
.flatMap((p) =>
p.flattenedTasks.filter(
(t: Task) =>
t.taskStatus == Task.Status.Available ||
t.taskStatus == Task.Status.DueSoon ||
t.taskStatus == Task.Status.Next ||
t.taskStatus == Task.Status.Overdue
)
);

let weightedTasks: [Task, number][] = [];

for (let task of possibleTasks) {
// weight some categories higher than others
let categoryWeight = 0;
let category = categorizeTask(task);
if (category) {
categoryWeight = weights[category];
}

// weight stale-er tasks higher, up to 7 days
let ageWeight = Math.min(7, daysBetween(now, task.modified)) / 7;

// weight due-er tasks higher, up to 100 points
let dueWeight = 0;
if (task.effectiveDueDate) {
dueWeight = 100 - daysBetween(now, task.effectiveDueDate);
}

weightedTasks.push([task, ageWeight + dueWeight + categoryWeight]);
}

return weightedRandom(weightedTasks);
};

var action = new PlugIn.Action(async () => {
try {
console.log(`task: ${chooseATask()}`);
} catch (err) {
console.error(err);
throw err;
}
});

return action;
})();
13 changes: 13 additions & 0 deletions Gardening.omnifocusjs/manifest.json
@@ -0,0 +1,13 @@
{
"author": "Brian Hicks",
"identifier": "zone.bytes.gardening",
"defaultLocale": "en",
"version": "1.0",
"description": "Digital Gardening in OmniFocus",
"actions": [
{
"identifier": "pick",
"image": "pick.png"
}
]
}
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -25,3 +25,4 @@ Except for third-party icons and assets listed below, this code is released unde
Exceptions:

- The Linear logo icon is provided by [Linear in their Brand Guidelines](https://linear.app/docs/brand-guidelines) section, and does not have a license listed.
- Other image icons from [Josh Hughes](https://omnifocusicons.josh-hughes.com/), licensed under "Please feel free to use the icons as you see fit"
2 changes: 1 addition & 1 deletion flake.nix
Expand Up @@ -9,6 +9,6 @@
let pkgs = import inputs.nixpkgs { inherit system; };
in {
devShell =
pkgs.mkShell { packages = [ pkgs.nodePackages.typescript ]; };
pkgs.mkShell { packages = [ pkgs.nodePackages.typescript pkgs.nodePackages.prettier ]; };
});
}
2 changes: 1 addition & 1 deletion tsconfig.json
Expand Up @@ -12,7 +12,7 @@

/* Language and Environment */
"target": "es2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"lib": ["es7"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"lib": ["es2019"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
Expand Down

0 comments on commit 632bc3f

Please sign in to comment.