BOINC /
boinc
| 1 | #! /usr/bin/env php |
||
| 2 | |||
|
0 ignored issues
–
show
Coding Style
introduced
by
Loading history...
|
|||
| 3 | <?php |
||
|
0 ignored issues
–
show
|
|||
| 4 | // This file is part of BOINC. |
||
| 5 | // http://boinc.berkeley.edu |
||
| 6 | // Copyright (C) 2008 University of California |
||
| 7 | // |
||
| 8 | // BOINC is free software; you can redistribute it and/or modify it |
||
| 9 | // under the terms of the GNU Lesser General Public License |
||
| 10 | // as published by the Free Software Foundation, |
||
| 11 | // either version 3 of the License, or (at your option) any later version. |
||
| 12 | // |
||
| 13 | // BOINC is distributed in the hope that it will be useful, |
||
| 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
| 15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
| 16 | // See the GNU Lesser General Public License for more details. |
||
| 17 | // |
||
| 18 | // You should have received a copy of the GNU Lesser General Public License |
||
| 19 | // along with BOINC. If not, see <http://www.gnu.org/licenses/>. |
||
| 20 | |||
| 21 | // remind.php [--lapsed | --failed] [--show_email] [--userid ID] |
||
| 22 | // |
||
| 23 | // --lapsed |
||
| 24 | // Send emails to lapsed user (see below) |
||
| 25 | // --failed |
||
| 26 | // Send emails to failed user (see below) |
||
| 27 | // --userid |
||
| 28 | // Send both "lapsed" and "failed" emails to the given user, |
||
| 29 | // regardless of whether they are due to be sent. |
||
| 30 | // The --lapsed and --failed options are ignored. |
||
| 31 | // (for testing) |
||
| 32 | // --show_email |
||
| 33 | // Show the text that would be mailed |
||
| 34 | // --explain |
||
| 35 | // Show which users would be sent email and why |
||
| 36 | // --send |
||
| 37 | // Actually send emails (this is an option to encourage |
||
| 38 | // you to do thorough testing before using it) |
||
| 39 | // --count N |
||
| 40 | // By default send to all users that qualify, but if count is |
||
| 41 | // set, only send to N users at a time |
||
| 42 | // |
||
| 43 | // This program sends "reminder" emails to |
||
| 44 | // - failed users: those who |
||
| 45 | // 1) were created at least $start_interval seconds ago, |
||
| 46 | // 2) have zero total credit |
||
| 47 | // 3) haven't been sent an email in at least $email_interval seconds. |
||
| 48 | // These people typically either had a technical glitch, |
||
| 49 | // or their prefs didn't allow sending them work, |
||
| 50 | // or the app crashed on their host. |
||
| 51 | // The email should direct them to a web page that helps |
||
| 52 | // them fix the startup problem. |
||
| 53 | // |
||
| 54 | // Set $start_interval according to your project's delay bounds |
||
| 55 | // e.g. (1 or 2 weeks). |
||
| 56 | /// $email_interval should be roughly 1 month - |
||
| 57 | // we don't want to bother people too often. |
||
| 58 | // |
||
| 59 | // - lapsed users: those who |
||
| 60 | // 1) have positive total credit, |
||
| 61 | // 2) haven't done a scheduler RPC within the past |
||
| 62 | // $lapsed_interval seconds, and |
||
| 63 | // 3) haven't been sent an email in at least $email_interval seconds. |
||
| 64 | // The email should gently prod them to start running the project again. |
||
| 65 | // |
||
| 66 | |||
| 67 | $cli_only = true; |
||
| 68 | require_once("../inc/util_ops.inc"); |
||
| 69 | require_once("../inc/email.inc"); |
||
| 70 | |||
| 71 | db_init(); |
||
| 72 | set_time_limit(0); |
||
| 73 | |||
| 74 | $globals->start_interval = 14*86400; |
||
| 75 | $globals->email_interval = 200*86400; |
||
| 76 | $globals->lapsed_interval = 60*86400; |
||
| 77 | $globals->do_failed = false; |
||
| 78 | $globals->do_lapsed = false; |
||
| 79 | $globals->show_email = false; |
||
| 80 | $globals->send = false; |
||
| 81 | $globals->explain = false; |
||
| 82 | $globals->userid = 0; |
||
| 83 | $globals->count = -1; |
||
| 84 | |||
| 85 | for ($i=1; $i<$argc; $i++) { |
||
| 86 | if ($argv[$i] == "--failed") { |
||
| 87 | $globals->do_failed = true; |
||
| 88 | } elseif ($argv[$i] == "--lapsed") { |
||
| 89 | $globals->do_lapsed = true; |
||
| 90 | } elseif ($argv[$i] == "--show_email") { |
||
| 91 | $globals->show_email = true; |
||
| 92 | } elseif ($argv[$i] == "--explain") { |
||
| 93 | $globals->explain = true; |
||
| 94 | } elseif ($argv[$i] == "--send") { |
||
| 95 | $globals->send = true; |
||
| 96 | } elseif ($argv[$i] == "--userid") { |
||
| 97 | $i++; |
||
| 98 | $globals->userid = $argv[$i]; |
||
| 99 | } elseif ($argv[$i] == "--count") { |
||
| 100 | $i++; |
||
| 101 | $globals->count = $argv[$i]; |
||
| 102 | } else { |
||
| 103 | echo "unrecognized option $argv[$i]\n"; |
||
| 104 | echo "usage: remind.php [--failed ] [--lapsed] [--userid N] [--show_mail] [--explain] [--send] [--count N]\n"; |
||
| 105 | exit (1); |
||
| 106 | } |
||
| 107 | } |
||
| 108 | |||
| 109 | // File names for the various mail types. |
||
| 110 | // Change these here if needed. |
||
| 111 | // |
||
| 112 | $dir = "remind_email"; |
||
| 113 | $failed_html = "$dir/reminder_failed_html"; |
||
| 114 | $failed_text = "$dir/reminder_failed_text"; |
||
| 115 | $failed_subject = "$dir/reminder_failed_subject"; |
||
| 116 | $lapsed_html = "$dir/reminder_lapsed_html"; |
||
| 117 | $lapsed_text = "$dir/reminder_lapsed_text"; |
||
| 118 | $lapsed_subject = "$dir/reminder_lapsed_subject"; |
||
| 119 | |||
| 120 | // return time of last scheduler RPC from this user, |
||
| 121 | // or zero if they're never done one |
||
| 122 | // |
||
| 123 | function last_rpc_time($user) { |
||
| 124 | $x = 0; |
||
| 125 | $result = _mysql_query("select rpc_time from host where userid=$user->id"); |
||
| 126 | while ($host = _mysql_fetch_object($result)) { |
||
| 127 | if ($host->rpc_time > $x) $x = $host->rpc_time; |
||
| 128 | } |
||
| 129 | _mysql_free_result($result); |
||
| 130 | return $x; |
||
| 131 | } |
||
| 132 | |||
| 133 | function read_files(&$item) { |
||
| 134 | $item['html'] = @file_get_contents($item['html_file']); |
||
| 135 | if (!$item['html']) { |
||
|
0 ignored issues
–
show
This
if statement is empty and can be removed.
This check looks for the bodies of These if (rand(1, 6) > 3) {
//print "Check failed";
} else {
print "Check succeeded";
}
could be turned into if (rand(1, 6) <= 3) {
print "Check succeeded";
}
This is much more concise to read. Loading history...
|
|||
| 136 | //$x = $item['html_file']; |
||
| 137 | //echo "file missing: $x\n"; |
||
| 138 | //exit(); |
||
| 139 | } |
||
| 140 | $item['text'] = @file_get_contents($item['text_file']); |
||
| 141 | if (!$item['text']) { |
||
| 142 | $x = $item['text_file']; |
||
| 143 | echo "file missing: $x\n"; |
||
| 144 | exit(); |
||
|
0 ignored issues
–
show
|
|||
| 145 | } |
||
| 146 | $item['subject'] = @file_get_contents($item['subject']); |
||
| 147 | if (!$item['subject']) { |
||
| 148 | $x = $item['subject']; |
||
| 149 | echo "file missing: $x\n"; |
||
| 150 | exit(); |
||
|
0 ignored issues
–
show
|
|||
| 151 | } |
||
| 152 | } |
||
| 153 | |||
| 154 | function read_email_files() { |
||
| 155 | global $failed_html; |
||
| 156 | global $failed_text; |
||
| 157 | global $failed_subject; |
||
| 158 | global $lapsed_html; |
||
| 159 | global $lapsed_text; |
||
| 160 | global $lapsed_subject; |
||
| 161 | |||
| 162 | $failed['html_file'] = $failed_html; |
||
| 163 | $failed['text_file'] = $failed_text; |
||
| 164 | $failed['subject'] = $failed_subject; |
||
| 165 | $lapsed['html_file'] = $lapsed_html; |
||
| 166 | $lapsed['text_file'] = $lapsed_text; |
||
| 167 | $lapsed['subject'] = $lapsed_subject; |
||
| 168 | read_files($failed); |
||
| 169 | read_files($lapsed); |
||
| 170 | $email_files['failed'] = $failed; |
||
| 171 | $email_files['lapsed'] = $lapsed; |
||
| 172 | return $email_files; |
||
| 173 | } |
||
| 174 | |||
| 175 | function replace($user, $template) { |
||
| 176 | $pat = array( |
||
| 177 | '/<name\/>/', |
||
| 178 | '/<email\/>/', |
||
| 179 | '/<create_time\/>/', |
||
| 180 | '/<total_credit\/>/', |
||
| 181 | '/<opt_out_url\/>/', |
||
| 182 | '/<user_id\/>/', |
||
| 183 | '/<lapsed_interval\/>/', |
||
| 184 | ); |
||
| 185 | $rep = array( |
||
| 186 | $user->name, |
||
| 187 | $user->email_addr, |
||
| 188 | gmdate('d F Y', $user->create_time), |
||
| 189 | number_format($user->total_credit, 0), |
||
| 190 | opt_out_url($user), |
||
| 191 | $user->id, |
||
| 192 | floor ((time() - last_rpc_time($user)) / 86400), |
||
| 193 | ); |
||
| 194 | return preg_replace($pat, $rep, $template); |
||
| 195 | } |
||
| 196 | |||
| 197 | function mail_type($user, $type) { |
||
| 198 | global $globals; |
||
| 199 | global $email_files; |
||
| 200 | |||
| 201 | $email_file = $email_files[$type]; |
||
| 202 | if ($email_file['html']) { |
||
| 203 | $html = replace($user, $email_file['html']); |
||
| 204 | } else { |
||
| 205 | $html = null; |
||
| 206 | } |
||
| 207 | $text = replace($user, $email_file['text']); |
||
| 208 | if ($globals->show_email) { |
||
| 209 | echo "------- SUBJECT ----------\n"; |
||
| 210 | echo $email_file['subject']; |
||
| 211 | echo "\n------- HTML ----------\n"; |
||
| 212 | echo $html; |
||
| 213 | echo "\n------- TEXT ----------\n"; |
||
| 214 | echo $text; |
||
| 215 | } |
||
| 216 | if ($globals->send) { |
||
| 217 | echo "sending to $user->email_addr\n"; |
||
| 218 | echo send_email( |
||
| 219 | $user, |
||
| 220 | $email_file['subject'], |
||
| 221 | $text, |
||
| 222 | $html |
||
| 223 | ); |
||
| 224 | $now = time(); |
||
| 225 | $ntype = 0; |
||
| 226 | if ($type == 'lapsed') $ntype = 2; |
||
| 227 | if ($type == 'failed') $ntype = 3; |
||
| 228 | $query = "insert into sent_email values($user->id, $now, $ntype)"; |
||
| 229 | _mysql_query($query); |
||
| 230 | } |
||
| 231 | $globals->count--; |
||
| 232 | if ($globals->count == 0) { |
||
| 233 | echo "reached limit set by --count - exiting...\n"; |
||
| 234 | exit(); |
||
|
0 ignored issues
–
show
|
|||
| 235 | } |
||
| 236 | } |
||
| 237 | |||
| 238 | function last_reminder_time($user) { |
||
| 239 | $query = "select * from sent_email where userid=$user->id"; |
||
| 240 | $result = _mysql_query($query); |
||
| 241 | $t = 0; |
||
| 242 | while ($r = _mysql_fetch_object($result)) { |
||
| 243 | if ($r->email_type !=2 && $r->email_type != 3) continue; |
||
| 244 | if ($r->time_sent > $t) $t = $r->time_sent; |
||
| 245 | |||
| 246 | } |
||
| 247 | _mysql_free_result($result); |
||
| 248 | return $t; |
||
| 249 | } |
||
| 250 | |||
| 251 | function handle_user($user, $do_type) { |
||
| 252 | global $globals; |
||
| 253 | global $email_interval; |
||
| 254 | |||
| 255 | if ($user->send_email == 0) { |
||
| 256 | if ($globals->explain) { |
||
| 257 | echo "user: $user->id send_email = 0\n"; |
||
| 258 | } |
||
| 259 | return; |
||
| 260 | } |
||
| 261 | $max_email_time = time() - $globals->email_interval; |
||
| 262 | if (last_reminder_time($user) > $max_email_time) { |
||
| 263 | if ($globals->explain) { |
||
| 264 | echo "user: $user->id sent too recently\n"; |
||
| 265 | } |
||
| 266 | return; |
||
| 267 | } |
||
| 268 | if ($globals->explain) { |
||
| 269 | $x = (time() - $user->create_time)/86400; |
||
| 270 | $t = last_rpc_time($user); |
||
| 271 | $show_lapsed_interval = (time()-$t)/86400; |
||
| 272 | echo "user $user->id ($user->email_addr) was created $x days ago\n"; |
||
| 273 | echo " total_credit: $user->total_credit; last RPC $show_lapsed_interval days ago\n"; |
||
| 274 | echo " sending $do_type email\n"; |
||
| 275 | } |
||
| 276 | mail_type($user, $do_type); |
||
| 277 | } |
||
| 278 | |||
| 279 | function do_failed() { |
||
| 280 | global $globals; |
||
| 281 | |||
| 282 | $max_create_time = time() - $globals->start_interval; |
||
| 283 | $result = _mysql_query( |
||
| 284 | "select * from user where send_email<>0 and create_time<$max_create_time and total_credit = 0;" |
||
| 285 | ); |
||
| 286 | while ($user = _mysql_fetch_object($result)) { |
||
| 287 | handle_user($user, 'failed'); |
||
| 288 | } |
||
| 289 | _mysql_free_result($result); |
||
| 290 | } |
||
| 291 | |||
| 292 | function do_lapsed() { |
||
| 293 | global $globals; |
||
| 294 | $max_last_rpc_time = time() - $globals->lapsed_interval; |
||
| 295 | |||
| 296 | // the following is an efficient way of getting the list of |
||
| 297 | // users for which no host has done an RPC recently |
||
| 298 | // |
||
| 299 | $result = _mysql_query( |
||
| 300 | "select userid from host group by userid having max(rpc_time)<$max_last_rpc_time;" |
||
| 301 | ); |
||
| 302 | while ($host = _mysql_fetch_object($result)) { |
||
| 303 | $uresult = _mysql_query("select * from user where id = $host->userid;"); |
||
| 304 | $user = _mysql_fetch_object($uresult); |
||
| 305 | _mysql_free_result($uresult); |
||
| 306 | if (!$user) { |
||
| 307 | echo "Can't find user $host->userid\n"; |
||
| 308 | continue; |
||
| 309 | } |
||
| 310 | handle_user($user, 'lapsed'); |
||
| 311 | } |
||
| 312 | _mysql_free_result($result); |
||
| 313 | } |
||
| 314 | |||
| 315 | if (!function_exists('make_php_mailer')) { |
||
| 316 | echo "You must use PHPMailer (http://phpmailer.sourceforge.net)\n"; |
||
| 317 | exit(); |
||
| 318 | } |
||
| 319 | |||
| 320 | $email_files = read_email_files(); |
||
| 321 | |||
| 322 | if ($globals->userid) { |
||
| 323 | $user = BoincUser::lookup_id($globals->userid); |
||
| 324 | if (!$user) { |
||
| 325 | echo "No such user: $globals->userid\n"; |
||
| 326 | exit(); |
||
| 327 | } |
||
| 328 | $user->last_rpc_time = last_rpc_time($user); |
||
| 329 | mail_type($user, 'failed'); |
||
| 330 | mail_type($user, 'lapsed'); |
||
| 331 | } else { |
||
| 332 | if ($globals->do_failed) { |
||
| 333 | do_failed(); |
||
| 334 | } |
||
| 335 | if ($globals->do_lapsed) { |
||
| 336 | do_lapsed(); |
||
| 337 | } |
||
| 338 | } |
||
| 339 | |||
| 340 | ?> |
||
| 341 |