[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/infrastructure/daemon/bot/handler/ -> PhabricatorBotMacroHandler.php (source)

   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  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1