Implement script to warn about unfinished tasks
[SonOfLokstallBot.git] / common.php
index a6e9212..f07c970 100644 (file)
@@ -45,11 +45,11 @@ function partition(int $numPartitions, $array) {
     $partitionSize = (int)ceil(count($array) / $numPartitions);
 
     return
-        filter(notEmpty)(
+        array_values(filter(notEmpty)(
             map(function($p) use ($array, $partitionSize) {
                 return array_slice($array, $p*$partitionSize, $partitionSize);
             })(range(0, $numPartitions-1))
-        );
+        ));
 }
 
 function getInbox($inbox) {
@@ -216,14 +216,15 @@ function ∪($a, $b) {
     return array_merge($a, $b);
 }
 
-function getSeason($monthNum) {
-    return ['summer', 'autumn', 'winter', 'spring'][floor(($monthNum)%12/3)];
+function getSeason(int $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];
 }
 
+// XXX: Consider renaming these to "is[First/Last]WeekOf[Month/Season]"
 function isStartOfSeason($monthNum, $dayNum) {
     return ($monthNum)%3 == 0 && isStartOfMonth($dayNum);
 }
@@ -232,6 +233,18 @@ function isStartOfMonth($dayNum) {
     return $dayNum < 8;
 }
 
+function isEndOfSeason($yearNum, $monthNum, $dayNum) {
+    return ($monthNum+1)%3 == 0 && isEndOfMonth($yearNum, $monthNum, $dayNum);
+}
+
+function isEndOfMonth($yearNum, $monthNum, $dayNum) {
+    return $dayNum + 7 > cal_days_in_month(CAL_GREGORIAN, $monthNum, $yearNum);
+}
+
+function isEndOfYear($yearNum, $monthNum, $dayNum) {
+    return $monthNum == 12 && isEndOfMonth($yearNum, $monthNum, $dayNum);
+}
+
 function getTasksForTheSeason($season, $taskMatrix) {
     return array_unique(
         array_reduce(
@@ -263,15 +276,49 @@ function getTasksForTheMonth($monthNum, $taskMatrix) {
     );
 }
 
-// NB weeknum is 1-4 (the week of the month, not consistent with other things)
-function getTasksForTheWeek($weekNum, $monthNum, $taskMatrix) {
+function getTasksForTheWeek(int $weekNum, int $monthNum, array $taskMatrix) {
     return  array_merge(
         $weekNum % 2 == 0 ? $taskMatrix['bimonthly'] : [],
         $taskMatrix['annualy'][getSeason($monthNum)][getMonthName($monthNum)]['weekly'] ?? [],
-        partition(4, getTasksForTheMonth($monthNum, $taskMatrix))[$weekNum]
+        partition(4, getTasksForTheMonth($monthNum, $taskMatrix))[$weekNum-1]
+    );
+}
+
+const getFilePathForWeek = 'getFilePathForWeek';
+function getFilePathForWeek(int $year, int $monthNum, int $weekNum) {
+    // December is part of next year's summer
+    $seasonYear = $year;
+    return sprintf(
+        'tasks/%s/%s/%s/week%s.txt',
+        $seasonYear,
+        getSeason($monthNum),
+        getMonthName($monthNum),
+        $weekNum
     );
 }
 
+function getFilePathsForMonth(int $year, int $monthNum) {
+    return map(function($week) use ($year, $monthNum){
+        return getFilePathForWeek($year, $monthNum, $week);
+    })(range(1,4));
+}
+
+function getFilePathsForSeason(int $year, string $season) {
+    return array_merge(...map(function($monthNum) use ($year) {
+        // Summer of the current year includes december of the previous year.
+        $seasonYear = $year - ($monthNum == 12 ? 1 : 0);
+        return getFilePathsForMonth($seasonYear, $monthNum);
+    })(array_filter(range(1,12), function($month) use ($season) {
+        return getSeason($month) == $season;
+    })));
+}
+
+function getFilePathsForYear(int $year) {
+    return array_merge(...map(function($season) use ($year) {
+        return getFilePathsForSeason($year, $season);
+    })(['summer', 'winter', 'spring', 'autumn']));
+}
+
 function closest($n, $list) {
     $a = array_filter($list, function($value) use ($n) {
         return $value <= $n;