MTrackWeb/Cron/Notify.php
[web.mtrack] / MTrackWeb / Cron / Notify.php
1 <?php
2
3 class MTrackWeb_Cron_Notify extends MTrackWeb
4 {
5     
6     function getAuth()
7     {
8         $ff = HTML_FlexyFramework::get();
9         if (!$ff->cli) {
10             die("access denied");
11         }
12         HTML_FlexyFramework::ensureSingle(__FILE__, $this);
13         return true;
14         
15     }
16     
17     function get()    
18     {
19     
20         date_default_timezone_set('UTC');
21         
22         // what's the baserul..
23     
24         
25         $MAX_DIFF = 200 * 1024;
26         $USE_BATCHING = false;
27         
28         
29         $db = MTrackDB::get();
30         
31         // default to the last 10 minutes, but prefer the last recorded run time
32         $last = MTrackDB::unixtime(time() - 600);
33         foreach (MTrackDB::q('select last_run from last_notification')->fetchAll()
34             as $row) {
35           $last = $row[0];
36         }
37         $LATEST = strtotime($last);
38         if (getenv('DEBUG_TIME')) {
39           $dtime = strtotime(getenv('DEBUG_TIME'));
40           if ($dtime > 0) {
41             $LATEST = $dtime;
42             $last = MTrackDB::unixtime($LATEST);
43             echo "Using $last as last time (specified via DEBUG_TIME var)\n";
44           }
45         }
46         
47         class CanonicalLineEndingFilter extends php_user_filter {
48           function filter($in, $out, &$consumed, $closing)
49           {
50             while ($bucket = stream_bucket_make_writeable($in)) {
51               $bucket->data = preg_replace("/\r?\n/", "\r\n", $bucket->data);
52               $consumed += $bucket->datalen;
53               stream_bucket_append($out, $bucket);
54             }
55             return PSFS_PASS_ON;
56           }
57         }
58         class UnixLineEndingFilter extends php_user_filter {
59           function filter($in, $out, &$consumed, $closing)
60           {
61             while ($bucket = stream_bucket_make_writeable($in)) {
62               $bucket->data = preg_replace("/\r?\n/", "\n", $bucket->data);
63               $consumed += $bucket->datalen;
64               stream_bucket_append($out, $bucket);
65             }
66             return PSFS_PASS_ON;
67           }
68         }
69         stream_filter_register("mtrackcanonical", 'CanonicalLineEndingFilter');
70         stream_filter_register("mtrackunix", 'UnixLineEndingFilter');
71         
72         $watched = MTrackWatch::getWatchedItemsAndWatchers($last, 'email');
73         printf("Got %d watchers\n", count($watched));
74         
75         /* For each watcher, compute the changes.
76          * Group changes by ticket, sending one email per ticket.
77          * Group tickets into batch updates if the only fields that changed are
78          * bulk update style (milestone, assignment etc.)
79          *
80          * For the wiki repo, group by file so that serial edits within the batch
81          * period show up as a single email.
82          */
83         
84         foreach ($watched as $user => $objects) {
85           $udata = MTrackAuth::getUserData($user);
86         
87           foreach ($objects as $object => $items) {
88             list($otype, $oid) = explode(':', $object, 2);
89         
90             $fname = "notify_$otype";
91             if (function_exists($fname)) {
92               call_user_func($fname, $object, $oid, $items, $user, $udata);
93             } else {
94               echo "WARN: no notifier for $otype $oid\n";
95             }
96             foreach ($items as $o) {
97               if ($o instanceof MTrackSCMEvent) {
98                 $t = strtotime($o->ctime);
99               } else {
100                 $t = strtotime($o->changedate);
101               }
102               if ($t > $LATEST) {
103                 $LATEST = $t;
104               }
105             }
106           }
107         }
108     }
109 }