MTrackWeb/Cron/Notify.php
authorAlan Knowles <alan@akbkhome.com>
Fri, 25 Mar 2011 10:41:24 +0000 (18:41 +0800)
committerAlan Knowles <alan@akbkhome.com>
Fri, 25 Mar 2011 10:41:24 +0000 (18:41 +0800)
MTrackWeb/Cron/Notify.php

index 162c369..9b56329 100644 (file)
@@ -9,11 +9,113 @@ class MTrackWeb_Cron_Notify extends MTrackWeb
         if (!$ff->cli) {
             die("access denied");
         }
+        HTML_FlexyFramework::ensureSingle(__FILE__, $this);
+        return true;
         
     }
     
     function get()    
     {
     
+        date_default_timezone_set('UTC');
+        
+        // what's the baserul..
+    
+        
+        $MAX_DIFF = 200 * 1024;
+        $USE_BATCHING = false;
+        
+        if (!$DEBUG) {
+          /* only allow one instance to run concurrently */
+          $lockfp = fopen($vardir . '/.notifier.lock', 'w');
+          if (!$lockfp) {
+            exit(1);
+          }
+          if (!flock($lockfp, LOCK_EX|LOCK_NB)) {
+            echo "Another instance is already running\n";
+            exit(1);
+          }
+          /* "leak" $lockfp, so that the lock is held while we continue to run */
+        }
+        
+        $db = MTrackDB::get();
+        
+        // default to the last 10 minutes, but prefer the last recorded run time
+        $last = MTrackDB::unixtime(time() - 600);
+        foreach (MTrackDB::q('select last_run from last_notification')->fetchAll()
+            as $row) {
+          $last = $row[0];
+        }
+        $LATEST = strtotime($last);
+        if (getenv('DEBUG_TIME')) {
+          $dtime = strtotime(getenv('DEBUG_TIME'));
+          if ($dtime > 0) {
+            $LATEST = $dtime;
+            $last = MTrackDB::unixtime($LATEST);
+            echo "Using $last as last time (specified via DEBUG_TIME var)\n";
+          }
+        }
+        
+        class CanonicalLineEndingFilter extends php_user_filter {
+          function filter($in, $out, &$consumed, $closing)
+          {
+            while ($bucket = stream_bucket_make_writeable($in)) {
+              $bucket->data = preg_replace("/\r?\n/", "\r\n", $bucket->data);
+              $consumed += $bucket->datalen;
+              stream_bucket_append($out, $bucket);
+            }
+            return PSFS_PASS_ON;
+          }
+        }
+        class UnixLineEndingFilter extends php_user_filter {
+          function filter($in, $out, &$consumed, $closing)
+          {
+            while ($bucket = stream_bucket_make_writeable($in)) {
+              $bucket->data = preg_replace("/\r?\n/", "\n", $bucket->data);
+              $consumed += $bucket->datalen;
+              stream_bucket_append($out, $bucket);
+            }
+            return PSFS_PASS_ON;
+          }
+        }
+        stream_filter_register("mtrackcanonical", 'CanonicalLineEndingFilter');
+        stream_filter_register("mtrackunix", 'UnixLineEndingFilter');
+        
+        $watched = MTrackWatch::getWatchedItemsAndWatchers($last, 'email');
+        printf("Got %d watchers\n", count($watched));
+        
+        /* For each watcher, compute the changes.
+         * Group changes by ticket, sending one email per ticket.
+         * Group tickets into batch updates if the only fields that changed are
+         * bulk update style (milestone, assignment etc.)
+         *
+         * For the wiki repo, group by file so that serial edits within the batch
+         * period show up as a single email.
+         */
+        
+        foreach ($watched as $user => $objects) {
+          $udata = MTrackAuth::getUserData($user);
+        
+          foreach ($objects as $object => $items) {
+            list($otype, $oid) = explode(':', $object, 2);
+        
+            $fname = "notify_$otype";
+            if (function_exists($fname)) {
+              call_user_func($fname, $object, $oid, $items, $user, $udata);
+            } else {
+              echo "WARN: no notifier for $otype $oid\n";
+            }
+            foreach ($items as $o) {
+              if ($o instanceof MTrackSCMEvent) {
+                $t = strtotime($o->ctime);
+              } else {
+                $t = strtotime($o->changedate);
+              }
+              if ($t > $LATEST) {
+                $LATEST = $t;
+              }
+            }
+          }
+        }
     }
 }
\ No newline at end of file