Fix bug where tasks weren't detected as all done after completing the last one
[SonOfLokstallBot.git] / src / purjolok.php
1 <?php declare(strict_types=1);
2
3 require_once('common.php');
4
5 use Telegram\Bot\Actions;
6 use Telegram\Bot\Commands\Command;
7
8 if(getTelegram()->getWebHookUpdates()->get('message') && !canChatWith(getTelegram()->getWebhookUpdates())) {
9 getTelegram()->sendMessage([
10 'chat_id' => getTelegram()->getWebhookUpdates()->get('message')->get('chat')->get('id'),
11 'text' => "Sorry, Dad says I can't talk to you."
12 ]);
13 exit(0);
14 }
15
16 $message = getTelegram()->getWebHookUpdates()->get('message') ? getTelegram()->getWebHookUpdates()->get('message')->get('text') : '';
17
18 if ($between = between(reveal($message ?? ''), '[taskid]')) {
19 // The actual date/time when the script is called
20 $currentYear = (int)(new DateTimeImmutable())->format('Y');
21 $currentMonth = (int)(new DateTimeImmutable())->format('n');
22 $currentDay = (int)(new DateTimeImmutable())->format('d');
23
24 // The years/months/weeks that we are "rewinding" to, for calculations
25 $yearForThisWeek = getYearWeekBeginsIn($currentYear, $currentMonth, $currentDay);
26 $monthForThisWeek = getMonthWeekBeginsIn($currentYear, $currentMonth, $currentDay);
27 $seasonForThisWeek = getSeason($monthForThisWeek);
28 $weekNum = getWeekNumber($currentYear, $currentMonth, $currentDay);
29
30 $completedTasksFile = getFilePathForWeek($yearForThisWeek, $monthForThisWeek, $weekNum);
31 $completedTasks = file_exists($completedTasksFile) ? lines(trim(file_get_contents($completedTasksFile))) : [];
32 $tasksForTheWeek = getTasksForTheWeek(
33 $yearForThisWeek,
34 $monthForThisWeek,
35 $weekNum,
36 require 'taskMatrix.php'
37 );
38
39 $chatid = getTelegram()->getWebhookUpdates()->get('message')->get('chat')->get('id');
40
41 if (!is_dir(dirname($completedTasksFile))) {
42 mkdir(dirname($completedTasksFile), 0777, true);
43 }
44
45 if (in_array($between, $completedTasks)) {
46 getTelegram()->sendMessage([
47 'chat_id' => $chatid,
48 'text' => getString('taskAlreadyCompleted')
49 ]);
50 return;
51 }
52
53 if (!in_array($between, $tasksForTheWeek)) {
54 getTelegram()->sendMessage([
55 'chat_id' => $chatid,
56 'text' => getString('unknownTask')
57 ]);
58 return;
59 }
60
61 file_put_contents(
62 $completedTasksFile,
63 "$between\n",
64 FILE_APPEND
65 );
66
67 getTelegram()->sendMessage([
68 'chat_id' => $chatid,
69 'text' => getString('taskCompleted'),
70 'reply_markup' => json_encode(['remove_keyboard' => true])
71 ]);
72
73 getTelegram()->sendSticker([
74 'chat_id' => $chatid,
75 'sticker' => 'CAADBQADOwAD__7RB2i3XcCiO8HuAg'
76 ]);
77
78 if (!array_diff($tasksForTheWeek, array_merge($completedTasks, [$between]))) {
79 getTelegram()->sendMessage([
80 'chat_id' => $chatid,
81 'text' => getString('heyTasksAllCompleted')
82 ]);
83 }
84 }
85
86 if ($between = between(reveal($message ?? ''), '[billid]')) {
87 $messages = array_values(array_filter(
88 getMessagesFromInbox(
89 getInbox(
90 'Utilities/' . getMessageSender(getTelegram()->getWebhookUpdates()) . ' To Pay'
91 ),
92 require 'rules.php',
93 FALSE
94 ),
95 function($e) use ($between) {
96 return $e['id'] == $between;
97 }
98 ));
99
100 if(!$messages || count($messages) !== 1) {
101 getTelegram()->sendMessage([
102 'chat_id' => getTelegram()->getWebhookUpdates()->get('message')->get('chat')->get('id'),
103 'text' => "That doesn't look like a valid id. Use /mybills to list your bills."
104 ]);
105 return;
106 }
107
108 imap_delete(getInbox('Utilities/' . getMessageSender(getTelegram()->getWebhookUpdates()) . ' To Pay'), $messages[0]['uid'], FT_UID);
109 getTelegram()->sendMessage([
110 'chat_id' => getTelegram()->getWebhookUpdates()->get('message')->get('chat')->get('id'),
111 'text' => "I marked " . getMessageSenderDisplayName(getTelegram()->getWebHookUpdates()) . " as having paid the " . strtolower($messages[0]['service']) . " bill.",
112 'reply_markup' => json_encode(['remove_keyboard' => true])
113 ]);
114
115 getTelegram()->sendSticker([
116 'chat_id' => getTelegram()->getWebhookUpdates()->get('message')->get('chat')->get('id'),
117 'sticker' => 'CAADBQADOwAD__7RB2i3XcCiO8HuAg'
118 ]);
119 }
120
121 getTelegram()->addCommand(
122 new class extends Command {
123 protected $name = 'searchmovies';
124 protected $description = 'Search through the movie collection';
125
126 public function handle($arguments) {
127 $top5 =(unlines, aaray_column('title'), aaray_slice(0)(5), 'array_reverse', 'array_values', ssort((f(field('similarity')),, field('similarity'))));
128 $movies = map(function($movie) use ($arguments) {
129 similar_text($arguments, substr($movie, 0, -7) ?: '', $perc);
130 return ['title' => $movie, 'similarity' => $perc];
131 })(scandir('/mnt/media/Movies'));
132
133 $this->replyWithMessage(
134 [
135 'text' => "Here are the most similar movies titles I could find...\n\n" . $top5($movies)
136 ]
137 );
138 }
139 }
140 );
141
142 getTelegram()->addCommand(
143 new class extends Command {
144 protected $name = 'chatid';
145 protected $description = 'Get the id for this chat.';
146
147 public function handle($arguments) {
148 $this->replyWithMessage([
149 'text' => $this->getUpdate()->get('message')->get('chat')->get('id')
150 ]);
151 }
152 }
153 );
154
155 getTelegram()->addCommand(
156 new class extends Command {
157 protected $name = 'mybills';
158 protected $description = 'List my bills';
159
160 public function handle($arguments) {
161 $this->replyWithMessage(['text' => 'Fetching ' . getMessageSenderDisplayName($this->getUpdate()) . "'s unpaid bills. Just a sec ..."]);
162 $this->replyWithChatAction(['action' => Actions::TYPING]);
163 $this->replyWithMessage([
164 'text' => implode(
165 "\n",
166 array_map(
167 function($bill) {
168 return sprintf(
169 "%s: $%s each due on the %s",
170 $bill['service'],
171 splitBill($bill['amount']),
172 $bill['due']->format('jS \of M')
173 );
174 },
175 getMessagesFromInbox(
176 getInbox(
177 'Utilities/' . getMessageSender($this->getUpdate()) . ' To Pay'
178 ),
179 require 'rules.php',
180 FALSE
181 )
182 ) ?: ['You have no unpaid bills! Nice one.']
183 )
184 ]);
185 }
186 }
187 );
188
189 getTelegram()->addCommand(
190 new class extends Command {
191 protected $name = 'paybill';
192 protected $description = 'Mark a bill as paid';
193
194 public function handle($arguments) {
195 $buttons = [array_values(map(function($bill) {
196 return sprintf('%s%s', hide('[billid]' . $bill['id'] . '[billid]'), $bill['service'] . ' ($' . splitBill($bill['amount']) . ')');
197 })(getMessagesFromInbox(
198 getInbox(
199 'Utilities/' . getMessageSender($this->getUpdate()) . ' To Pay'
200 ),
201 require 'rules.php',
202 FALSE
203 )))];
204
205 if (!$buttons[0]) {
206 $this->replyWithMessage([
207 'text' => getMessageSenderDisplayName($this->getUpdate()). ' doesn\'t have any outstanding bills. Nice :)',
208 'reply_markup' => json_encode(['remove_keyboard' => true])
209 ]);
210 return;
211 }
212
213 $reply_markup = getTelegram()->replyKeyboardMarkup([
214 'keyboard' => $buttons,
215 'resize_keyboard' => true,
216 'one_time_keyboard' => true,
217 'selective' => true
218 ]);
219
220 $this->replyWithMessage(
221 [
222 'text' => '[' . getMessageSenderDisplayName($this->getUpdate()) . '](tg://user?id=' . getMessageSenderId($this->getUpdate()) . '), which bill did you want to pay?',
223 'parse_mode' => 'markdown',
224 'reply_markup' => $reply_markup
225 ]
226 );
227 }
228 }
229
230 );
231
232 getTelegram()->addCommand(
233 new class extends Command {
234 protected $name = 'tasks';
235 protected $description = 'List tasks for this week';
236
237 public function handle($arguments) {
238 // The actual date/time when the script is called
239 $currentYear = (int)(new DateTimeImmutable())->format('Y');
240 $currentMonth = (int)(new DateTimeImmutable())->format('n');
241 $currentDay = (int)(new DateTimeImmutable())->format('d');
242
243 // The years/months/weeks that we are "rewinding" to, for calculations
244 $yearForThisWeek = getYearWeekBeginsIn($currentYear, $currentMonth, $currentDay);
245 $monthForThisWeek = getMonthWeekBeginsIn($currentYear, $currentMonth, $currentDay);
246 $seasonForThisWeek = getSeason($monthForThisWeek);
247 $weekNum = getWeekNumber($currentYear, $currentMonth, $currentDay);
248
249 $tasksForTheWeek = getTasksForTheWeek(
250 $yearForThisWeek,
251 $monthForThisWeek,
252 $weekNum,
253 require 'taskMatrix.php'
254 );
255
256 $completedTasksFile = getFilePathForWeek($yearForThisWeek, $monthForThisWeek, $weekNum);
257 $completedTasks = file_exists($completedTasksFile) ? lines(trim(file_get_contents($completedTasksFile))) : [];
258
259 if (!array_diff($tasksForTheWeek, $completedTasks)) {
260 $this->replyWithMessage([
261 'text' => getString('tasksAllCompleted')
262 ]);
263 return;
264 }
265
266 $this->replyWithMessage([
267 'text' => ununlines([
268 getString('tasksForTheWeek'),
269 unlines(map(getString)(array_diff($tasksForTheWeek, $completedTasks)))
270 ])
271 ]);
272 }
273 }
274 );
275
276 getTelegram()->addCommand(
277 new class extends Command {
278 protected $name = 'completetask';
279 protected $description = 'Mark a task as completed';
280
281 public function handle($arguments) {
282 // The actual date/time when the script is called
283 $currentYear = (int)(new DateTimeImmutable())->format('Y');
284 $currentMonth = (int)(new DateTimeImmutable())->format('n');
285 $currentDay = (int)(new DateTimeImmutable())->format('d');
286
287 // The years/months/weeks that we are "rewinding" to, for calculations
288 $yearForThisWeek = getYearWeekBeginsIn($currentYear, $currentMonth, $currentDay);
289 $monthForThisWeek = getMonthWeekBeginsIn($currentYear, $currentMonth, $currentDay);
290 $seasonForThisWeek = getSeason($monthForThisWeek);
291 $weekNum = getWeekNumber($currentYear, $currentMonth, $currentDay);
292
293 $tasksForTheWeek = getTasksForTheWeek(
294 $yearForThisWeek,
295 $monthForThisWeek,
296 $weekNum,
297 require 'taskMatrix.php'
298 );
299
300 $completedTasksFile = getFilePathForWeek($yearForThisWeek, $monthForThisWeek, $weekNum);
301 $completedTasks = file_exists($completedTasksFile) ? lines(trim(file_get_contents($completedTasksFile))) : [];
302
303 if (!array_diff($tasksForTheWeek, $completedTasks)) {
304 $this->replyWithMessage([
305 'text' => getString('tasksAllCompleted')
306 ]);
307 return;
308 }
309
310 $tasks = array_values(map(function($task) {
311 return sprintf('%s%s', hide('[taskid]' . $task . '[taskid]'), getString($task));
312 })(array_diff($tasksForTheWeek, $completedTasks)));
313 $buttons = partition((int)ceil(count($tasks)/3), $tasks);
314 $reply_markup = getTelegram()->replyKeyboardMarkup([
315 'keyboard' => $buttons,
316 'resize_keyboard' => true,
317 'one_time_keyboard' => true,
318 'selective' => true
319 ]);
320
321 $this->replyWithMessage(
322 [
323 'text' => '[' . getMessageSenderDisplayName($this->getUpdate()) . '](tg://user?id=' . getMessageSenderId($this->getUpdate()) . '), which task did you finish?',
324 'parse_mode' => 'markdown',
325 'reply_markup' => $reply_markup
326 ]
327 );
328 }
329 }
330 );
331
332 getTelegram()->commandsHandler(true); //must come afterwards because lolzer