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         $e= DB_DataObject::factory('Events');
30         $e->action = 'MTrack.Notify';
31         
32         // default to the last 10 minutes, but prefer the last recorded run time
33         $last = MTrackDB::unixtime(time() - 600);
34         foreach (MTrackDB::q('select last_run from last_notification')->fetchAll()
35             as $row) {
36           $last = $row[0];
37         }
38         $LATEST = strtotime($last);
39         if (getenv('DEBUG_TIME')) {
40           $dtime = strtotime(getenv('DEBUG_TIME'));
41           if ($dtime > 0) {
42             $LATEST = $dtime;
43             $last = MTrackDB::unixtime($LATEST);
44             echo "Using $last as last time (specified via DEBUG_TIME var)\n";
45           }
46         }
47         
48         
49         stream_filter_register("mtrackcanonical", 'CanonicalLineEndingFilter');
50         stream_filter_register("mtrackunix", 'UnixLineEndingFilter');
51         
52         $watched = MTrackWatch::getWatchedItemsAndWatchers($last, 'email');
53         printf("Got %d watchers\n", count($watched));
54         
55         /* For each watcher, compute the changes.
56          * Group changes by ticket, sending one email per ticket.
57          * Group tickets into batch updates if the only fields that changed are
58          * bulk update style (milestone, assignment etc.)
59          *
60          * For the wiki repo, group by file so that serial edits within the batch
61          * period show up as a single email.
62          */
63         
64         foreach ($watched as $user => $objects) {
65           $udata = MTrackAuth::getUserData($user);
66         
67           foreach ($objects as $object => $items) {
68             list($otype, $oid) = explode(':', $object, 2);
69         
70             $fname = "notify_$otype";
71             if (function_exists($fname)) {
72               call_user_func($fname, $object, $oid, $items, $user, $udata);
73             } else {
74               echo "WARN: no notifier for $otype $oid\n";
75             }
76             foreach ($items as $o) {
77               if ($o instanceof MTrackSCMEvent) {
78                 $t = strtotime($o->ctime);
79               } else {
80                 $t = strtotime($o->changedate);
81               }
82               if ($t > $LATEST) {
83                 $LATEST = $t;
84               }
85             }
86           }
87         }
88     }
89 }
90
91
92 class CanonicalLineEndingFilter extends php_user_filter {
93     function filter($in, $out, &$consumed, $closing)
94     {
95       while ($bucket = stream_bucket_make_writeable($in)) {
96         $bucket->data = preg_replace("/\r?\n/", "\r\n", $bucket->data);
97         $consumed += $bucket->datalen;
98         stream_bucket_append($out, $bucket);
99       }
100       return PSFS_PASS_ON;
101     }
102     }
103     class UnixLineEndingFilter extends php_user_filter {
104     function filter($in, $out, &$consumed, $closing)
105     {
106       while ($bucket = stream_bucket_make_writeable($in)) {
107         $bucket->data = preg_replace("/\r?\n/", "\n", $bucket->data);
108         $consumed += $bucket->datalen;
109         stream_bucket_append($out, $bucket);
110       }
111       return PSFS_PASS_ON;
112     }
113     }