Fix 'glue' constnat
[SonOfLokstallBot.git] / common.php
1 <?php declare(strict_types=1);
2
3 require_once('vendor/autoload.php');
4 require_once(__DIR__ . '/config.php');
5
6 use Telegram\Bot\Api;
7
8 function getTelegram(): \Telegram\Bot\Api {
9 STATIC $tg;
10 return $tg = $tg ?? new \Telegram\Bot\Api(BOT_TOKEN);
11 }
12
13 function splitBill($amount) {
14 return floor($amount/2);
15 }
16
17 function identity($x) {
18 return $x;
19 }
20
21 function getMessageSender($update) {
22 return PARTICIPANT_IDS[$update->get('message')->get('from')->get('id')];
23 }
24
25 function getMessageSenderDisplayName($update) {
26 return $update->get('message')->get('from')->get('first_name');
27 }
28
29 function canChatWith($update) {
30 return in_array($update->get('message')->get('from')->get('id'), array_keys(PARTICIPANT_IDS));
31 }
32
33 function debug($whatever) {
34 echo '<pre>';
35 print_r($whatever);
36 echo '</pre>';
37 }
38
39 function getInbox($inbox) {
40 STATIC $inboxes;
41
42 if (!isset($inboxes[$inbox])) {
43 $inboxes[$inbox] = imap_open(
44 '{imap.gmail.com:993/debug/imap/ssl/novalidate-cert}' . $inbox,
45 EMAIL,
46 PASSWORD
47 );
48 }
49
50 return $inboxes[$inbox];
51 }
52
53 function getRules() {
54 STATIC $rules;
55 return $rules = $rules ?? require 'rules.php';
56 }
57
58 function getString($identifier, ...$vars) {
59 STATIC $strings;
60 $strings = $strings ?? require 'strings.php';
61
62 return sprintf($strings[$identifier], ...$vars);
63 }
64
65 function formatDate($date) {
66 return $date->format(DATE_FORMAT);
67 }
68
69 function ssort($comparitor) {
70 return function($array) use ($comparitor) {
71 uasort($array, uncurry($comparitor));
72 return $array;
73 };
74 }
75
76 function uncurry($f) {
77 return function($a, $b) use ($f) {
78 return $f($a)($b);
79 };
80 }
81
82 const sendToGroupChat = 'sendToGroupChat';
83 function sendToGroupChat(string $message) {
84 return getTelegram()->sendMessage(['chat_id' => CHAT_ID, 'text' => $message]);
85 }
86
87 const generateReminderText = 'generateReminderText';
88 function generateReminderText($message) {
89 return getString('billreminder', REMIND_THRESHOLD, $message['service'], splitBill($message['amount']), formatDate($message['due']));
90 }
91
92 const generateNewBillText = 'generateNewBillText';
93 function generateNewBillText($message) {
94 return getString('newbill', $message['service'], splitBill($message['amount']), formatDate($message['due']));
95 }
96
97 const messageNeedsReminder = 'messageNeedsReminder';
98 function messageNeedsReminder($message) {
99 return $message['due']->diff(new DateTimeImmutable)->d == REMIND_THRESHOLD;
100 }
101
102 const lines = 'lines';
103 function lines(string $string): array {
104 return explode("\n", $string);
105 }
106
107 const glue = 'glue';
108 function glue(string $delim): callable {
109 return function(array $strings) use ($delim): string {
110 return implode($delim, $strings);
111 };
112 }
113
114 const unlines = 'unlines';
115 function unlines($lines) {
116 return implode("\n", $lines);
117 }
118
119 function field($field) {
120 return function($array) use ($field) {
121 return $array[$field];
122 };
123 }
124
125 const= '⬄';
126 function($a) {
127 return function($b) use ($a) {
128 return $a <=> $b;
129 };
130 }
131
132
133 function(...$fs) {
134 return function($arg) use ($fs) {
135 return array_reduce(array_reverse($fs), function($c, $f) {
136 return $f($c);
137 }, $arg);
138 };
139 }
140
141 function map($callable) {
142 return function($list) use ($callable) {
143 return array_map($callable, $list);
144 };
145 }
146
147 function aaray_column($column) {
148 return function($array) use ($column) {
149 return array_column($array, $column);
150 };
151 }
152
153 function aaray_slice($start) {
154 return function($length) use ($start) {
155 return function($array) use ($length, $start) {
156 return array_slice($array, $start, $length);
157 };
158 };
159 }
160
161 function filter($callable) {
162 return function($list) use ($callable) {
163 return array_filter($list, $callable);
164 };
165 }
166
167 function f∘(callable $f) {
168 return function(callable $g) use ($f) {
169 return function($arg) use($g, $f) {
170 return $f($g($arg));
171 };
172 };
173 }
174
175 functionf(callable $f) {
176 return function(callable $g) use ($f) {
177 return function($arg) use($g, $f) {
178 return $g($f($arg));
179 };
180 };
181 }
182
183 function($a, $b) {
184 return array_merge($a, $b);
185 }
186
187 function getMessagesFromInbox($inbox, array $rules, $unseenOnly = true) {
188 return array_filter(
189 array_map(
190 function($rule, $service) use ($inbox, $unseenOnly) {
191 $emails = imap_search($inbox, ['SEEN ', 'UNSEEN '][$unseenOnly] . $rule['imapQuery'], SE_UID);
192
193 if(!$emails) {
194 return [];
195 }
196
197 $messageTransform = $rule['messageTransform'] ?? 'identity';
198 $dateTransform = $rule['dateTransform'] ?? 'identity';
199
200 $body = quoted_printable_decode(imap_fetchbody($inbox, $emails[0], '1', FT_UID));
201 preg_match($rule['regex'], $messageTransform($body), $matches);
202
203 return [
204 'service' => $service,
205 'id' => substr(md5($body), 0, 6),
206 'uid' => $emails[0],
207 'due' => new DateTimeImmutable($dateTransform($matches['due'])),
208 'amount' => $matches['amount']
209 ];
210 },
211 $rules,
212 array_keys($rules)
213 ),
214 function($e) {
215 return !!$e;
216 }
217 );
218 }