Improved logic in tasks and unfinished scripts plus some bug fixes
authorCameron Ball <cameron@cameron1729.xyz>
Fri, 4 Jan 2019 08:29:16 +0000 (16:29 +0800)
committerCameron Ball <cameron@cameron1729.xyz>
Sat, 5 Jan 2019 19:28:49 +0000 (03:28 +0800)
src/common.php
src/strings.php
src/tasks.php
src/unfinished.php

index 173bd32..bc627f4 100644 (file)
@@ -43,11 +43,11 @@ function canChatWith(TelegramUpdate $update) : bool {
 function partition(int $numPartitions, array $array) : array {
     $partitionSize = (int)ceil(count($array) / $numPartitions);
 
-    return array_values(filter(notEmpty)(
+    return array_values(
         map(function($p) use ($array, $partitionSize) {
             return array_slice($array, $p*$partitionSize, $partitionSize);
         })(range(0, $numPartitions-1))
-    ));
+    );
 }
 
 function getInbox(string $inbox) {
@@ -260,7 +260,7 @@ function getTasksForTheSeason($season, $taskMatrix) {
                 return array_merge(
                     $c,
                     array_reduce($v, function($c, $v) {
-                        return array_merge($c, is_array($v) ? $v : [$v]);
+                        return array_merge($c, is_array($v) ? [] : [$v]);
                     }, [])
                 );
             },
@@ -283,11 +283,11 @@ function getTasksForTheMonth($monthNum, $taskMatrix) {
     );
 }
 
-function getTasksForTheWeek(int $weekNum, int $monthNum, array $taskMatrix) {
+function getTasksForTheWeek(int $year, int $monthNum, int $weekNum, array $taskMatrix) {
     return  array_merge(
         $weekNum % 2 == 0 ? $taskMatrix['bimonthly'] : [],
         $taskMatrix['annualy'][getSeason($monthNum)][getMonthName($monthNum)]['weekly'] ?? [],
-        partition(4, getTasksForTheMonth($monthNum, $taskMatrix))[$weekNum-1]
+        partition(count(getMondaysForMonth($year, $monthNum)), getTasksForTheMonth($monthNum, $taskMatrix))[$weekNum-1]
     );
 }
 
@@ -304,10 +304,77 @@ function getFilePathForWeek(int $year, int $monthNum, int $weekNum) {
     );
 }
 
+function getMondaysForMonth(int $year, int $monthNum) {
+    $dt = DateTimeImmutable::createFromFormat('Y n', "$year $monthNum");
+    $m = $dt->format('F');
+    $y = $dt->format('Y');
+    $fifthMonday = (int)(new DateTimeImmutable("fifth monday of $m $y"))->format('d');
+    $mondays = [
+        (int)(new DateTimeImmutable("first monday of $m $y"))->format('d'),
+        (int)(new DateTimeImmutable("second monday of $m $y"))->format('d'),
+        (int)(new DateTimeImmutable("third monday of $m $y"))->format('d'),
+        (int)(new DateTimeImmutable("fourth monday of $m $y"))->format('d'),
+    ];
+
+    return array_merge(
+        $mondays,
+        $fifthMonday > $mondays[3] ? [$fifthMonday] : []
+    );
+}
+
+function getDayNumber(int $year, int $month, int $day) {
+    $potentialMondays = array_filter(
+        getMondaysForMonth($year, $month),
+        function($monday) use ($day) {
+            return $monday <= $day;
+        }
+    );
+
+    return $potentialMondays
+        ? closest($day, $potentialMondays)
+        : array_values(
+            array_slice(
+                getMondaysForMonth(
+                    getYearWeekBeginsIn($year, $month, $day),
+                    getMonthWeekBeginsIn($year, $month, $day)
+                ),
+                -1
+            )
+        )[0];
+}
+
+function getWeekNumber(int $year, int $month, int $day) {
+    $potentialMondays = array_filter(
+        getMondaysForMonth($year, $month),
+        function($monday) use ($day) {
+            return $monday <= $day;
+        }
+    );
+
+    return $potentialMondays
+        ? closestIndex($day, $potentialMondays) + 1
+        : count(
+            getMondaysForMonth(
+                getYearWeekBeginsIn($year, $month, $day),
+                getMonthWeekBeginsIn($year, $month, $day)
+            )
+        );
+}
+
+function getMonthWeekBeginsIn(int $year, int $month, int $day) {
+    return array_merge([12], range(1,11), [12])[
+        $month - ($day < getMondaysForMonth($year, $month)[0] ? 1 : 0)
+    ];
+}
+
+function getYearWeekBeginsIn(int $year, int $month, int $day) {
+    return $year - (int)($month == 1 && getMonthWeekBeginsIn($year, $month, $day) == 12);
+}
+
 function getFilePathsForMonth(int $year, int $monthNum) {
     return map(function($week) use ($year, $monthNum){
         return getFilePathForWeek($year, $monthNum, $week);
-    })(range(1,4));
+    })(range(1, count(getMondaysForMonth($year, $monthNum))));
 }
 
 function getFilePathsForSeason(int $year, string $season) {
@@ -326,7 +393,7 @@ function getFilePathsForYear(int $year) {
     })(['summer', 'winter', 'spring', 'autumn']));
 }
 
-function closestIndex($n, array $list) {
+function closestIndex(int $n, array $list) {
     $a = map(function(int $v) use ($n) : int {
             return (int)abs($v - $n);
         })
@@ -336,7 +403,7 @@ function closestIndex($n, array $list) {
     return array_keys($a)[0];
 }
 
-function closest($n, array $list) : int {
+function closest(int $n, array $list) : int {
     return $list[closestIndex($n, $list)];
 }
 
index 4350620..38e4266 100644 (file)
@@ -44,8 +44,8 @@ return [
     'endOfSpring' => 'Spring is almost over, and there are still some outstanding tasks. Try to get them done because I won\'t be reminding you again until next year :o',
     'endOfSpringGood' => 'Spring is about to end! And you did everything that needed doing. Epic!',
 
-    'endOfMonth' => 'November is coming to a close, and there are still some tasks outstanding. Try your best to get them done...',
-    'endOfMonthGood' => 'November is almost over, and it looks like you\'ve completed everything! Nice one!',
+    'endOfMonth' => 'The month is coming to a close, and there are still some tasks outstanding. Try your best to get them done...',
+    'endOfMonthGood' => 'The month is almost over, and it looks like you\'ve completed everything! Nice one!',
     'andAlsoEndOfMonth' => 'Also, it\'s the end of the month, and there are these monthly tasks that still need doing...',
     'andAlsoEndOfMonthGood' => 'It\'s the end of the month too, and you did all the tasks! Nice.',
     'endOfWeek' => 'Aw geez Rick, it\'s Friday and these tasks still haven\'nt been completed, please try to do them over the weekend D:',
index eb37cc7..38ecb83 100644 (file)
@@ -3,31 +3,34 @@
 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 = (int)(new DateTimeImmutable())->format('m');
-$currentDayOfMonth = closest((new DateTimeImmutable())->format('d'), $mondays);
-$currentWeekOfMonth = closestIndex($currentDayOfMonth, $mondays) + 1;
+
+// The actual date/time when the script is called
+$currentYear = (int)(new DateTimeImmutable())->format('Y');
+$currentMonth = (int)(new DateTimeImmutable())->format('n');
+$currentDay = (int)(new DateTimeImmutable())->format('d');
+
+// The years/months/weeks that we are "rewinding" to, for calculations
+$yearForThisWeek = getYearWeekBeginsIn($currentYear, $currentMonth, $currentDay);
+$monthForThisWeek = getMonthWeekBeginsIn($currentYear, $currentMonth, $currentDay);
+$seasonForThisWeek = getSeason($monthForThisWeek);
+$weekNum = getWeekNumber($currentYear, $currentMonth, $currentDay);
+$dayNum = getDayNumber($currentYear, $currentMonth, $currentDay);
 
 $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)))]
+    isStartOfSeason($monthForThisWeek, $dayNum) ? [unlines(map(getString)(getTasksForTheSeason($seasonForThisWeek, $taskMatrix)))] : [],
+    isStartOfMonth($dayNum) ? [unlines(map(getString)(getTasksForTheMonth($monthForThisWeek, $taskMatrix)))] : [],
+    [unlines(map(getString)(getTasksForTheWeek($yearForThisWeek, $monthForThisWeek, $weekNum, $taskMatrix)))]
 );
 
 $taskMessages = [
     [getString('happyMonday')],
     [
-        [getString('beginningOf'. ucfirst(getMonthName($currentMonth))), getString('thisMonthThereAre', count(getTasksForTheMonth($currentMonth, $taskMatrix)))],
+        [getString('beginningOf'. ucfirst(getMonthName($monthForThisWeek))), getString('thisMonthThereAre', count(getTasksForTheMonth($monthForThisWeek, $taskMatrix)))],
          getString('anywayHeresTheWeek')
     ],
     [
-        getString('beginningOf' . ucfirst(getSeason($currentMonth))),
-        [getString('anywayHeresTheMonth'), getString('thisMonthThereAre', count(getTasksForTheMonth($currentMonth, $taskMatrix)))],
+        getString('beginningOf' . ucfirst(getSeason($monthForThisWeek))),
+        [getString('anywayHeresTheMonth'), getString('thisMonthThereAre', count(getTasksForTheMonth($monthForThisWeek, $taskMatrix)))],
         getString('finallyHeresTheWeek')
     ]
 ];
@@ -43,7 +46,7 @@ $messages = zipWith(
     },
     // Magic. startOfSeason implies 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[(int)isStartOfSeason($currentMonth, $currentDayOfMonth) + (int)isStartOfMonth($currentDayOfMonth)],
+    $taskMessages[(int)isStartOfSeason($monthForThisWeek, $dayNum) + (int)isStartOfMonth($dayNum)],
     $taskLists
 );
 
index 8c7369d..b106c76 100644 (file)
@@ -4,18 +4,17 @@ 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 = (int)(new DateTimeImmutable())->format('n');
-$currentDayOfMonth = closest((new DateTimeImmutable())->format('d'), $mondays);
-$currentSeason = getSeason($currentMonth);
+// The actual date/time when the script is called
 $currentYear = (int)(new DateTimeImmutable())->format('Y');
-$currentWeekOfMonth = closestIndex($currentDayOfMonth, $mondays) + 1;
+$currentMonth = (int)(new DateTimeImmutable())->format('n');
+$currentDay = (int)(new DateTimeImmutable())->format('d');
+
+// The years/months/weeks that we are "rewinding" to, for calculations
+$yearForThisWeek = getYearWeekBeginsIn($currentYear, $currentMonth, $currentDay);
+$monthForThisWeek = getMonthWeekBeginsIn($currentYear, $currentMonth, $currentDay);
+$seasonForThisWeek = getSeason($monthForThisWeek);
+$weekNum = getWeekNumber($currentYear, $currentMonth, $currentDay);
+$dayNum = getDayNumber($currentYear, $currentMonth, $currentDay);
 
 $extractTasks = function($tasks, $path) {
     return array_merge($tasks, file_exists($path) ? lines(trim(file_get_contents($path))) : []);
@@ -27,35 +26,35 @@ $unfinishedForYear = array_diff(
              return getTasksForTheSeason($season, $taskMatrix);
          }
      )(['summer', 'autumn', 'winter', 'spring'])),
-     array_reduce(getFilePathsForYear($currentYear), $extractTasks, [])
+     array_reduce(getFilePathsForYear($yearForThisWeek), $extractTasks, [])
 );
 
 $unfinishedForSeason = array_diff(
-    getTasksForTheSeason($currentSeason, $taskMatrix),
-    array_reduce(getFilePathsForSeason($currentYear, $currentSeason), $extractTasks, [])
+    getTasksForTheSeason($seasonForThisWeek, $taskMatrix),
+    array_reduce(getFilePathsForSeason($yearForThisWeek, $seasonForThisWeek), $extractTasks, [])
 );
 
 $unfinishedForMonth = array_diff(
-    getTasksForTheMonth($currentMonth, $taskMatrix),
-    array_reduce(getFilePathsForMonth($currentYear, $currentMonth), $extractTasks, [])
+    getTasksForTheMonth($monthForThisWeek, $taskMatrix),
+    array_reduce(getFilePathsForMonth($yearForThisWeek, $monthForThisWeek), $extractTasks, [])
 );
 
-$filePathForWeek = getFilePathForWeek($currentYear, $currentMonth, $currentWeekOfMonth);
+$filePathForWeek = getFilePathForWeek($yearForThisWeek, $monthForThisWeek, $weekNum);
 $unfinishedForWeek = array_diff(
-    getTasksForTheWeek($currentWeekOfMonth, $currentMonth, $taskMatrix),
+    getTasksForTheWeek($yearForThisWeek, $monthForThisWeek, $weekNum, $taskMatrix),
     file_exists($filePathForWeek) ? lines(trim(file_get_contents($filePathForWeek))) : []
 );
 
 //EOY => (EOM & EOW) & !EOSx
 //EOS => (EOM & EOW) & !EOY
 $taskLists = array_merge(
-    isEndOfYear($currentYear, $currentMonth, $currentDayOfMonth) ? [unlines(map(getString)($unfinishedForYear))] : [],
-    isEndOfSeason($currentYear, $currentMonth, $currentDayOfMonth) ? [unlines(map(getString)($unfinishedForSeason))] : [],
-    isEndOfMonth($currentYear, $currentMonth, $currentDayOfMonth) ? [unlines(map(getString)($unfinishedForMonth))] : [],
+    isEndOfYear($yearForThisWeek, $monthForThisWeek, $dayNum) ? [unlines(map(getString)($unfinishedForYear))] : [],
+    isEndOfSeason($yearForThisWeek, $monthForThisWeek, $dayNum) ? [unlines(map(getString)($unfinishedForSeason))] : [],
+    isEndOfMonth($yearForThisWeek, $monthForThisWeek, $dayNum) ? [unlines(map(getString)($unfinishedForMonth))] : [],
     [unlines(map(getString)($unfinishedForWeek))]
 );
 
-$seasonName = ucfirst($currentSeason);
+$seasonName = ucfirst($seasonForThisWeek);
 $goodOrBad = function($string, $goodOrBad) {
     return getString($string . ($goodOrBad ? '' : 'Good'));
 };
@@ -89,9 +88,9 @@ $messages = zipWith(
     },
     // Similar magic to tasks.php
     $taskMessages[
-        isEndOfMonth($currentYear, $currentMonth, $currentDayOfMonth) +
-        isEndOfSeason($currentYear, $currentMonth, $currentDayOfMonth) +
-        (isEndOfYear($currentYear, $currentMonth, $currentDayOfMonth) ? 2 : 0) // EOY is independant of EOS, to get the right index need to add 2 instead of 1.
+        isEndOfMonth($yearForThisWeek, $monthForThisWeek, $dayNum) +
+        isEndOfSeason($yearForThisWeek, $monthForThisWeek, $dayNum) +
+        (isEndOfYear($yearForThisWeek, $monthForThisWeek, $dayNum) ? 2 : 0) // EOY is independant of EOS, to get the right index need to add 2 instead of 1.
     ],
     $taskLists
 );