config.php
.ac-php-conf.json
+tasks
return $x;
}
+const notEmpty = 'notEmpty';
+function notEmpty($value) {
+ return !empty($value);
+}
+
function getMessageSender($update) {
return PARTICIPANT_IDS[$update->get('message')->get('from')->get('id')];
}
echo '</pre>';
}
+function partition(int $numPartitions, $array) {
+ $partitionSize = (int)ceil(count($array) / $numPartitions);
+
+ return
+ filter(notEmpty)(
+ map(function($p) use ($array, $partitionSize) {
+ return array_slice($array, $p*$partitionSize, $partitionSize);
+ })(range(0, $numPartitions-1))
+ );
+}
+
function getInbox($inbox) {
STATIC $inboxes;
return $rules = $rules ?? require 'rules.php';
}
+const getString = 'getString';
function getString($identifier, ...$vars) {
STATIC $strings;
$strings = $strings ?? require 'strings.php';
- return sprintf($strings[$identifier], ...$vars);
+ return isset($strings[$identifier]) ? sprintf($strings[$identifier], ...$vars) : "[[$identifier]]";
}
function formatDate($date) {
return implode("\n", $lines);
}
+const ununlines = 'ununlines';
+function ununlines($lines) {
+ return implode("\n\n", $lines);
+}
+
+const zipWith = 'zipWith';
+function zipWith(callable $zipper, array $a, array $b) {
+ return array_map($zipper, $a, $b);
+}
+
function field($field) {
return function($array) use ($field) {
return $array[$field];
return array_merge($a, $b);
}
+function getSeason($monthNum) {
+ return ['summer', 'autumn', 'winter', 'spring'][floor(($monthNum)%12/3)];
+}
+
+function getMonthName($monthNum) {
+ return ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'][$monthNum-1];
+}
+
+function isStartOfSeason($monthNum, $dayNum) {
+ return ($monthNum)%3 == 0 && isStartOfMonth($dayNum);
+}
+
+function isStartOfMonth($dayNum) {
+ return $dayNum < 8;
+}
+
+function getTasksForTheSeason($season, $taskMatrix) {
+ return array_unique(
+ array_reduce(
+ $taskMatrix['annualy'][$season],
+ function($c, $v) {
+ return array_merge(
+ $c,
+ array_reduce($v, function($c, $v) {
+ return array_merge($c, is_array($v) ? $v : [$v]);
+ }, [])
+ );
+ },
+ []
+ )
+ );
+}
+
+function getTasksForTheMonth($monthNum, $taskMatrix) {
+ return array_merge(
+ $taskMatrix['monthly'],
+ $monthNum % 6 == 0 ? $taskMatrix['biannualy'] : [],
+ $monthNum % 3 == 0 ? $taskMatrix['quadriannualy'] : [],
+ array_filter(
+ $taskMatrix['annualy'][getSeason($monthNum)][getMonthName($monthNum)],
+ function($v) {
+ return !is_array($v);
+ }
+ )
+ );
+}
+
+// NB weeknum is 1-4 (the week of the month, not consistent with other things)
+function getTasksForTheWeek($weekNum, $monthNum, $taskMatrix) {
+ return array_merge(
+ $weekNum % 2 == 0 ? $taskMatrix['bimonthly'] : [],
+ $taskMatrix['annualy'][getSeason($monthNum)][getMonthName($monthNum)]['weekly'] ?? [],
+ partition(4, getTasksForTheMonth($monthNum, $taskMatrix))[$weekNum]
+ );
+}
+
+function closest($n, $list) {
+ $a = array_filter($list, function($value) use ($n) {
+ return $value <= $n;
+ });
+
+ arsort($a);
+ return array_values($a)[0];
+}
+
function getMessagesFromInbox($inbox, array $rules, $unseenOnly = true) {
return array_filter(
array_map(
);
+getTelegram()->addCommand(
+ new class extends Command {
+ protected $name = 'tasks';
+ protected $description = 'List tasks for this week';
+
+ public function handle($arguments) {
+ $dt = new DateTimeImmutable();
+ $directory = sprintf(
+ "tasks/%s/%s/%s",
+ $dt->format('Y'),
+ $dt->format('F'),
+ $dt->format('W')
+ );
+
+ $mondays = [
+ (int)(new DateTimeImmutable('first monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('second monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('third monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('fourth monday of this month'))->format('d'),
+ ];
+ $closestMonday = closest($dt->format('d'), $mondays);
+
+ $tasksForTheWeek = getTasksForTheWeek(
+ array_search($closestMonday, $mondays),
+ $dt->format('m'),
+ require 'taskMatrix.php'
+ );
+
+ $completedTasksFile = "$directory" . "/completed.txt";
+ $completedTasks = file_exists($completedTasksFile) ? lines(trim(file_get_contents($completedTasksFile))) : [];
+
+ $stringAndCode = function($string) {
+ return getString($string) . " (" . $string . ")";
+ };
+
+ $this->replyWithMessage([
+ 'text' => ununlines([
+ getString('tasksForTheWeek'),
+ unlines(map($stringAndCode)(array_diff($tasksForTheWeek, $completedTasks)))
+ ])
+ ]);
+ }
+ }
+);
+
+getTelegram()->addCommand(
+ new class extends Command {
+ protected $name = 'completetask';
+ protected $description = 'Mark a task as completed';
+
+ public function handle($arguments) {
+ $dt = new DateTimeImmutable();
+ $mondays = [
+ (int)(new DateTimeImmutable('first monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('second monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('third monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('fourth monday of this month'))->format('d'),
+ ];
+ $closestMonday = closest($dt->format('d'), $mondays);
+
+ $directory = sprintf(
+ "tasks/%s/%s/%s",
+ $dt->format('Y'),
+ $dt->format('F'),
+ $dt->format('W')
+ );
+
+ $tasksForTheWeek = getTasksForTheWeek(
+ array_search($closestMonday, $mondays),
+ $dt->format('m'),
+ require 'taskMatrix.php'
+ );
+
+ $completedTasksFile = "$directory" . "/completed.txt";
+ $completedTasks = file_exists($completedTasksFile) ? lines(trim(file_get_contents($completedTasksFile))) : [];
+
+ if (!is_dir($directory)) {
+ mkdir($directory, 0777, true);
+ }
+
+ if (in_array($arguments, $completedTasks)) {
+ $this->replyWithMessage(['text' => getString('taskAlreadyCompleted')]);
+ return;
+ }
+
+ if (!in_array($arguments, $tasksForTheWeek)) {
+ $this->replyWithMessage(['text' => getString('unknownTask')]);
+ return;
+ }
+
+ file_put_contents(
+ $completedTasksFile,
+ "$arguments\n",
+ FILE_APPEND
+ );
+
+ $this->replyWithMessage(['text' => getString('taskCompleted')]);
+ }
+ }
+);
+
getTelegram()->commandsHandler(true); //must come afterwards because lolzer
'drinksomewater' => '🚰 Consider drinking some water! 💦 #HydrationNation',
'goodnightWearShorts' => 'I\'m signing off for the night. Before I go; tomorrow it\'s going to be about %s when you get up and %s later in the day. So consider wearing summer clothes. ☀️☀️☀️',
'goodnightNormal' => 'I\'m signing off for the night. Before I go; tomorrow it\'s going to be about %s when you get up and %s later in the day. Jumper and trousers, maybe?',
- 'goodnight' => 'Goodnight!'
+ 'goodnight' => 'Goodnight!',
+
+ 'beginningOfSummer' => 'It\'s the start of summer! To get you prepared, here are the unique things that will happen this season (in addition to regular weekly(ish) shit)...',
+ 'beginningOfWinter' => 'It\'s the start of winter (at last, fuck summer). Heads up lads, here are the unique tasks that are wanting doing this season (in addition to regular junk)...',
+
+ 'beginningOfDecember' => 'Welcome to December! Oh boy!',
+ 'beginningOfJanuary' => 'Welcome to January! Oh boy.',
+
+ 'anywayHeresTheMonth' => 'Anyway, here\'s the normal start of the month breakdown...',
+ 'anywayHeresTheWeek' => 'Anyway, like normal here\'s some stuff I think you guys should do this week...',
+ 'finallyHeresTheWeek' => 'And finally... Like always, here\'s some stuff I think you guys should do this week:',
+ 'happyMonday' => 'Happy Monday! Here are some tasks I think should get nutted out this week:',
+
+ 'thisMonthThereAre' => 'This month there are %d tasks that need completing (as well as the regular tasks). I\'ll try my best to space them out over the coming weeks. As a heads up, here they are:',
+ 'seasonalMeme' => 'Please also enjoy this seasonal meme I picked for you: %s',
+ 'tasksForTheWeek' => 'Here are the incomplete tasks for this week...',
+ 'taskAlreadyCompleted' => 'Hmm... It looks as though that task was already done this week.',
+ 'taskCompleted' => 'Marked as completed, nice one!',
+ 'unknownTask' => 'That doesn\'t look like a task I asked you to do this week... Use the listtasks command to see all the tasks.',
+
+ 'rangehoodfilters' => 'Clean the rangehood filters in the kitchen',
+ 'poolwater' => 'Check the level of the pool, and fill if needed',
+ 'weeds' => 'Inspect pavers for weeds (front and back), and spray/pull out as needed',
+ 'ants' => 'Inspect the pavers for ant hills and apply sand/back fill as needed',
+ 'leaves' => 'Sweep up leaves in the front yard',
+ 'cobwebs' => 'Inspect the exterior of the house for cobwebs (in the windows and shit)',
+ 'fireextinguisher' => 'Inspect fire extinguisher',
+ 'mowlawn' => 'Mow the lawn',
+ 'vacuum' => 'Vacuum the house',
+ 'mop' => 'Mop the tiles',
+ 'kitchen' => 'Clean the kitchen (wipe all surfaces/cupboards and clean the stove)',
+ 'cleanhouse' => 'Do a big cleanout of the house',
+ 'cleangarage' => 'Do a big cleanout of the garage',
+ 'testreliefevalve' => 'Test the relief valves on the water heater',
+ 'testsmokealarms' => 'Test smoke alarms',
+ 'smokealarmbatteries' => 'Replace smoke alarm batteries',
+ 'fridgecoils' => 'Clean the fridge coils',
+ 'chlorinatorplates' => 'Inspect and descale chlorinator if needed',
+ 'treeflowers' => 'Clean up the flowers from that stupid tree next door',
+ 'bulkgreens' => 'Prepare for bulk greens collection',
+ 'windowdebris' => 'Clean junk out of windows (inside and outside)',
+ 'cleangutters' => 'Clean out gutters to prepare for rain',
+ 'checkdrains' => 'Check down pipe drains for blockages',
+ 'coverpool' => 'Cover the pool',
+ 'cleanchimeny' => 'Clean soot out of the chimney',
+ 'tightenfixings' => 'Inspect and tighten (if needed) any fixings',
+ 'fanfilters' => 'Clean extractor fan filters (bathroom and air conditioner)',
+ 'bulkrubbish' => 'Prepare for bulk rubbish collection',
+ 'caulking' => 'Inspect and repair caulking',
+ 'showerheads' => 'Inspect and descale showerheads and taps',
+ 'shrubs' => 'Prune shrubs',
+ 'palmtrees' => 'Remove dead branches and seeds from palm trees',
+ 'uncoverpool' => 'Uncover the pool',
+ 'checktaps' => 'Inspect taps for leaks and repair as needed'
];
--- /dev/null
+<?php declare(strict_types=1);
+
+// look in to termites cibtract
+
+return [
+ 'monthly' => ['rangehoodfilters', 'poolwater', 'weeds', 'ants', 'leaves', 'cobwebs', 'fireextinguisher', 'mowlawn'],
+ 'bimonthly' => ['vacuum', 'mop', 'kitchen'],
+ 'biannualy' => ['cleanhouse', 'cleangarage', 'testreliefevalve', 'smokealarmstest', 'smokealarmbatteries', 'fridgecoils'],
+ 'quadriannualy' => ['chlorinatorplates'],
+ 'annualy' => [
+ 'summer' => [
+ 'december' => [
+ 'weekly' => ['treeflowers']
+ ],
+ 'january' => [
+ 'bulkgreens',
+ 'weekly' => ['treeflowers']
+ ],
+ 'february' => []
+ ],
+ 'autumn' => [
+ 'march' => ['windowdebris'],
+ 'april' => ['cleangutters', 'checkdrains'],
+ 'may' => ['coverpool', 'cleanchimney']
+ ],
+ 'winter' => [
+ 'june' => ['tightenfixings', 'fanfilters'],
+ 'july' => ['bulkrubbish'],
+ 'august' => ['caulking', 'showerheads']
+ ],
+ 'spring' => [
+ 'september' => ['shrubs'],
+ 'october' => ['palmtrees', 'uncoverpool'],
+ 'november' => ['checktaps']
+ ]
+ ]
+];
+
+/*
+ clean computer files
+ clean car
+ vacuum bedroom
+ change bed sheets
+ clean bathroom
+ dust bathroom
+ clean shower
+*/
--- /dev/null
+<?php declare(strict_types=1);
+
+require_once('common.php');
+
+$taskMatrix = require 'taskMatrix.php';
+$mondays = [
+ (int)(new DateTimeImmutable('first monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('second monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('third monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('fourth monday of this month'))->format('d'),
+];
+$currentMonth = (new DateTimeImmutable())->format('m');
+$currentDayOfMonth = closest((new DateTimeImmutable())->format('d'), $mondays);
+$currentWeekOfMonth = array_search($currentDayOfMonth, $mondays);
+
+$taskLists = array_merge(
+ isStartOfSeason($currentMonth, $currentDayOfMonth) ? [unlines(map(getString)(getTasksForTheSeason(getSeason($currentMonth), $taskMatrix)))] : [],
+ isStartOfMonth($currentDayOfMonth) ? [unlines(map(getString)(getTasksForTheMonth($currentMonth, $taskMatrix)))] : [],
+ [unlines(map(getString)(getTasksForTheWeek($currentWeekOfMonth, $currentMonth, $taskMatrix)))]
+);
+
+$taskMessages = [
+ [getString('happyMonday')],
+ [
+ [getString('beginningOf'. ucfirst(getMonthName($currentMonth))), getString('thisMonthThereAre', count(getTasksForTheMonth($currentMonth, $taskMatrix)))],
+ getString('anywayHeresTheWeek')
+ ],
+ [
+ getString('beginningOf' . ucfirst(getSeason($currentMonth))),
+ [getString('anywayHeresTheMonth'), getString('thisMonthThereAre', count(getTasksForTheMonth($currentMonth, $taskMatrix)))],
+ getString('finallyHeresTheWeek')
+ ]
+];
+
+$messages = zipWith(
+ function($message, $list) {
+ return ununlines(
+ array_merge(
+ is_array($message) ? $message : [$message],
+ [$list]
+ )
+ );
+ },
+ // Magic. startOfSeason implis startofMonth so we get 2, start of month without start of season gives 1 and
+ // a regular week (not the start of a season or month) gives 0. And this is how the indicies are ordered in the array.
+ $taskMessages[isStartOfSeason($currentMonth, $currentDayOfMonth) + isStartOfMonth($currentDayOfMonth)],
+ $taskLists
+);
+
+foreach ($messages as $message) {
+ sendToGroupChat($message);
+ sleep(rand(2,4));
+}
+
+$seasonalMemes = [
+ 'summer' => ['https://www.youtube.com/watch?v=NqktmrKB3ko']
+];
+
+if (isStartOfSeason($currentMonth, $currentDayOfMonth)) {
+ sendToGroupChat(getString('seasonalMeme', $seasonalMemes[getSeason($currentMonth)][array_rand($seasonalMemes[getSeason($currentMonth)])]));
+}
--- /dev/null
+<?php
+
+require_once('common.php');
+
+$dt = new DateTimeImmutable();
+
+$mondays = [
+ (int)(new DateTimeImmutable('first monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('second monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('third monday of this month'))->format('d'),
+ (int)(new DateTimeImmutable('fourth monday of this month'))->format('d'),
+];
+
+$directory = sprintf(
+ "tasks/%s/%s/%s",
+ $dt->format('Y'),
+ $dt->format('F'),
+ $dt->format('W')
+);
+$completedTasksFile = "$directory" . "/completed.txt";
+$completedTasks = file_exists($completedTasksFile) ? lines(trim(file_get_contents($completedTasksFile))) : [];
+
+$closestMonday = closest($dt->format('d'), $mondays);
+
+$tasksForTheWeek = getTasksForTheWeek(
+ array_search($closestMonday, $mondays),
+ $dt->format('m'),
+ require 'taskMatrix.php'
+);
+
+$unfinished = array_diff($tasksForTheWeek, $completedTasks);
+
+print_r(
+ array_diff(['treeflowers', 'someothershit'], ['treeflowers'])
+);