[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Watches the feed and puts notifications into channel(s) of choice. 5 */ 6 final class PhabricatorBotFeedNotificationHandler 7 extends PhabricatorBotHandler { 8 9 private $startupDelay = 30; 10 private $lastSeenChronoKey = 0; 11 12 private $typesNeedURI = array('DREV', 'TASK'); 13 14 private function shouldShowStory($story) { 15 $story_objectphid = $story['objectPHID']; 16 $story_text = $story['text']; 17 18 $show = $this->getConfig('notification.types'); 19 20 if ($show) { 21 $obj_type = phid_get_type($story_objectphid); 22 if (!in_array(strtolower($obj_type), $show)) { 23 return false; 24 } 25 } 26 27 $verbosity = $this->getConfig('notification.verbosity', 3); 28 29 $verbs = array(); 30 31 switch ($verbosity) { 32 case 2: 33 $verbs[] = array( 34 'commented', 35 'added', 36 'changed', 37 'resigned', 38 'explained', 39 'modified', 40 'attached', 41 'edited', 42 'joined', 43 'left', 44 'removed', 45 ); 46 // fallthrough 47 case 1: 48 $verbs[] = array( 49 'updated', 50 'accepted', 51 'requested', 52 'planned', 53 'claimed', 54 'summarized', 55 'commandeered', 56 'assigned', 57 ); 58 // fallthrough 59 case 0: 60 $verbs[] = array( 61 'created', 62 'closed', 63 'raised', 64 'committed', 65 'abandoned', 66 'reclaimed', 67 'reopened', 68 'deleted', 69 ); 70 break; 71 72 case 3: 73 default: 74 return true; 75 } 76 77 $verbs = '/('.implode('|', array_mergev($verbs)).')/'; 78 79 if (preg_match($verbs, $story_text)) { 80 return true; 81 } 82 83 return false; 84 } 85 86 public function receiveMessage(PhabricatorBotMessage $message) { 87 return; 88 } 89 90 public function runBackgroundTasks() { 91 if ($this->startupDelay > 0) { 92 // the event loop runs every 1s so delay enough to fully conenct 93 $this->startupDelay--; 94 95 return; 96 } 97 if ($this->lastSeenChronoKey == 0) { 98 // Since we only want to post notifications about new stories, skip 99 // everything that's happened in the past when we start up so we'll 100 // only process real-time stories. 101 $latest = $this->getConduit()->callMethodSynchronous( 102 'feed.query', 103 array( 104 'limit' => 1, 105 )); 106 107 foreach ($latest as $story) { 108 if ($story['chronologicalKey'] > $this->lastSeenChronoKey) { 109 $this->lastSeenChronoKey = $story['chronologicalKey']; 110 } 111 } 112 113 return; 114 } 115 116 $config_max_pages = $this->getConfig('notification.max_pages', 5); 117 $config_page_size = $this->getConfig('notification.page_size', 10); 118 119 $last_seen_chrono_key = $this->lastSeenChronoKey; 120 $chrono_key_cursor = 0; 121 122 // Not efficient but works due to feed.query API 123 for ($max_pages = $config_max_pages; $max_pages > 0; $max_pages--) { 124 $stories = $this->getConduit()->callMethodSynchronous( 125 'feed.query', 126 array( 127 'limit' => $config_page_size, 128 'after' => $chrono_key_cursor, 129 'view' => 'text', 130 )); 131 132 foreach ($stories as $story) { 133 if ($story['chronologicalKey'] == $last_seen_chrono_key) { 134 // Caught up on feed 135 return; 136 } 137 if ($story['chronologicalKey'] > $this->lastSeenChronoKey) { 138 // Keep track of newest seen story 139 $this->lastSeenChronoKey = $story['chronologicalKey']; 140 } 141 if (!$chrono_key_cursor || 142 $story['chronologicalKey'] < $chrono_key_cursor) { 143 // Keep track of oldest story on this page 144 $chrono_key_cursor = $story['chronologicalKey']; 145 } 146 147 if (!$story['text'] || 148 !$this->shouldShowStory($story)) { 149 continue; 150 } 151 152 $message = $story['text']; 153 154 $story_object_type = phid_get_type($story['objectPHID']); 155 if (in_array($story_object_type, $this->typesNeedURI)) { 156 $objects = $this->getConduit()->callMethodSynchronous( 157 'phid.lookup', 158 array( 159 'names' => array($story['objectPHID']), 160 )); 161 $message .= ' '.$objects[$story['objectPHID']]['uri']; 162 } 163 164 $channels = $this->getConfig('join'); 165 foreach ($channels as $channel_name) { 166 167 $channel = id(new PhabricatorBotChannel()) 168 ->setName($channel_name); 169 170 $this->writeMessage( 171 id(new PhabricatorBotMessage()) 172 ->setCommand('MESSAGE') 173 ->setTarget($channel) 174 ->setBody($message)); 175 } 176 } 177 } 178 } 179 180 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |