[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class PhabricatorBotMacroHandler extends PhabricatorBotHandler { 4 5 private $macros; 6 private $regexp; 7 8 private $next = 0; 9 10 private function init() { 11 if ($this->macros === false) { 12 return false; 13 } 14 15 if ($this->macros !== null) { 16 return true; 17 } 18 19 $macros = $this->getConduit()->callMethodSynchronous( 20 'macro.query', 21 array()); 22 23 // If we have no macros, cache `false` (meaning "no macros") and return 24 // immediately. 25 if (!$macros) { 26 $this->macros = false; 27 return false; 28 } 29 30 $regexp = array(); 31 foreach ($macros as $macro_name => $macro) { 32 $regexp[] = preg_quote($macro_name, '/'); 33 } 34 $regexp = '/^('.implode('|', $regexp).')\z/'; 35 36 $this->macros = $macros; 37 $this->regexp = $regexp; 38 39 return true; 40 } 41 42 public function receiveMessage(PhabricatorBotMessage $message) { 43 if (!$this->init()) { 44 return; 45 } 46 47 switch ($message->getCommand()) { 48 case 'MESSAGE': 49 $message_body = $message->getBody(); 50 51 $matches = null; 52 if (!preg_match($this->regexp, trim($message_body), $matches)) { 53 return; 54 } 55 56 $macro = $matches[1]; 57 58 $ascii = idx($this->macros[$macro], 'ascii'); 59 if ($ascii === false) { 60 return; 61 } 62 63 if (!$ascii) { 64 $this->macros[$macro]['ascii'] = $this->rasterize( 65 $this->macros[$macro], 66 $this->getConfig('macro.size', 48), 67 $this->getConfig('macro.aspect', 0.66)); 68 $ascii = $this->macros[$macro]['ascii']; 69 } 70 71 if ($ascii === false) { 72 // If we failed to rasterize the macro, bail out. 73 return; 74 } 75 76 $target_name = $message->getTarget()->getName(); 77 foreach ($ascii as $line) { 78 $this->replyTo($message, $line); 79 } 80 break; 81 } 82 } 83 84 public function rasterize($macro, $size, $aspect) { 85 try { 86 $image = $this->getConduit()->callMethodSynchronous( 87 'file.download', 88 array( 89 'phid' => $macro['filePHID'], 90 )); 91 $image = base64_decode($image); 92 } catch (Exception $ex) { 93 return false; 94 } 95 96 if (!$image) { 97 return false; 98 } 99 100 $img = @imagecreatefromstring($image); 101 if (!$img) { 102 return false; 103 } 104 105 $sx = imagesx($img); 106 $sy = imagesy($img); 107 108 if ($sx > $size || $sy > $size) { 109 $scale = max($sx, $sy) / $size; 110 $dx = floor($sx / $scale); 111 $dy = floor($sy / $scale); 112 } else { 113 $dx = $sx; 114 $dy = $sy; 115 } 116 117 $dy = floor($dy * $aspect); 118 119 $dst = imagecreatetruecolor($dx, $dy); 120 if (!$dst) { 121 return false; 122 } 123 imagealphablending($dst, false); 124 125 $ok = imagecopyresampled( 126 $dst, $img, 127 0, 0, 128 0, 0, 129 $dx, $dy, 130 $sx, $sy); 131 132 if (!$ok) { 133 return false; 134 } 135 136 $map = array( 137 ' ', 138 '.', 139 ',', 140 ':', 141 ';', 142 '!', 143 '|', 144 '*', 145 '=', 146 '@', 147 '$', 148 '#', 149 ); 150 151 $lines = array(); 152 153 for ($ii = 0; $ii < $dy; $ii++) { 154 $buf = ''; 155 for ($jj = 0; $jj < $dx; $jj++) { 156 $c = imagecolorat($dst, $jj, $ii); 157 158 $a = ($c >> 24) & 0xFF; 159 $r = ($c >> 16) & 0xFF; 160 $g = ($c >> 8) & 0xFF; 161 $b = ($c) & 0xFF; 162 163 $luma = (255 - ((0.30 * $r) + (0.59 * $g) + (0.11 * $b))) / 256; 164 $luma *= ((127 - $a) / 127); 165 166 $char = $map[max(0, floor($luma * count($map)))]; 167 $buf .= $char; 168 } 169 170 $lines[] = $buf; 171 } 172 173 return $lines; 174 } 175 176 }
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 |