From 0a8b0d1392bd79b4e88fbf910b176c960d57b4b4 Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 14 Feb 2013 05:13:55 -0800 Subject: [PATCH] Merge IRCProtocolHandler into IRCAdapter Summary: Clearly silly to have a separate handler for this. I also made most of the protocol stuff direct writes so we don't need to ship them through handlers, and made the adapter ignore message it does not understand by default instead of sending them to IRC, and added PASTE "support". We could still let handlers react to these messages by emitting them all as 'RAWIRC' or similar, but there's currently no need for that so I didn't bother. Also fix an issue in D4924 with nickpass. Test Plan: Had bot join IRC, talked to it. Reviewers: indiefan Reviewed By: indiefan CC: aran Differential Revision: https://secure.phabricator.com/D4925 --- .../adapter/PhabricatorIRCProtocolAdapter.php | 117 ++++++++++-------- .../handler/PhabricatorIRCProtocolHandler.php | 36 +----- 2 files changed, 67 insertions(+), 86 deletions(-) diff --git a/src/infrastructure/daemon/bot/adapter/PhabricatorIRCProtocolAdapter.php b/src/infrastructure/daemon/bot/adapter/PhabricatorIRCProtocolAdapter.php index 970917d40e..a3d001cdbf 100644 --- a/src/infrastructure/daemon/bot/adapter/PhabricatorIRCProtocolAdapter.php +++ b/src/infrastructure/daemon/bot/adapter/PhabricatorIRCProtocolAdapter.php @@ -41,21 +41,11 @@ final class PhabricatorIRCProtocolAdapter } $this->socket = $socket; - $this->writeMessage( - id(new PhabricatorBotMessage()) - ->setCommand('USER') - ->setBody("{$user} 0 * :{$user}")); + $this->write("USER {$user} 0 * :{$user}"); if ($pass) { - $this->writeMessage( - id(new PhabricatorBotMessage()) - ->setCommand('PASS') - ->setBody("{$pass}")); + $this->write("PASS {$pass}"); } - - $this->writeMessage( - id(new PhabricatorBotMessage()) - ->setCommand('NICK') - ->setBody("{$nick}")); + $this->write("NICK {$nick}"); } public function getNextMessages($poll_frequency) { @@ -111,33 +101,31 @@ final class PhabricatorIRCProtocolAdapter } while (strlen($this->writeBuffer)); } - while ($m = $this->processReadBuffer()) { - $messages[] = $m; + while (($m = $this->processReadBuffer()) !== false) { + if ($m !== null) { + $messages[] = $m; + } } return $messages; } private function write($message) { - $this->writeBuffer .= $message; + $this->writeBuffer .= $message."\r\n"; return $this; } public function writeMessage(PhabricatorBotMessage $message) { - $irc_command = $this->getIRCCommand($message->getCommand()); switch ($message->getCommand()) { - case 'MESSAGE': - $data = $irc_command.' '. - $message->getTarget()->getName().' :'. - $message->getBody()."\r\n"; - break; - default: - $data = $irc_command.' '. - $message->getBody()."\r\n"; - break; + case 'MESSAGE': + case 'PASTE': + $name = $message->getTarget()->getName(); + $body = $message->getBody(); + $this->write("PRIVMSG {$name} :{$body}"); + return true; + default: + return false; } - - return $this->write($data); } private function processReadBuffer() { @@ -161,6 +149,10 @@ final class PhabricatorIRCProtocolAdapter throw new Exception("Unexpected message from server: {$message}"); } + if ($this->handleIRCProtocol($matches)) { + return null; + } + $command = $this->getBotCommand($matches['command']); list($target, $body) = $this->parseMessageData($command, $matches['data']); @@ -180,6 +172,31 @@ final class PhabricatorIRCProtocolAdapter return $bot_message; } + private function handleIRCProtocol(array $matches) { + $data = $matches['data']; + switch ($matches['command']) { + case '422': // Error - no MOTD + case '376': // End of MOTD + $nickpass = $this->getConfig('nickpass'); + if ($nickpass) { + $this->write("PRIVMSG nickserv :IDENTIFY {$nickpass}"); + } + $join = $this->getConfig('join'); + if (!$join) { + throw new Exception("Not configured to join any channels!"); + } + foreach ($join as $channel) { + $this->write("JOIN {$channel}"); + } + return true; + case 'PING': + $this->write("PONG {$data}"); + return true; + } + + return false; + } + private function getBotCommand($irc_command) { if (isset(self::$commandTranslations[$irc_command])) { return self::$commandTranslations[$irc_command]; @@ -189,36 +206,26 @@ final class PhabricatorIRCProtocolAdapter return $irc_command; } - private function getIRCCommand($original_bot_command) { - foreach (self::$commandTranslations as $irc_command=>$bot_command) { - if ($bot_command === $original_bot_command) { - return $irc_command; - } - } - - return $original_bot_command; - } - private function parseMessageData($command, $data) { switch ($command) { - case 'MESSAGE': - $matches = null; - if (preg_match('/^(\S+)\s+:?(.*)$/', $data, $matches)) { + case 'MESSAGE': + $matches = null; + if (preg_match('/^(\S+)\s+:?(.*)$/', $data, $matches)) { - $target_name = $matches[1]; - if (strncmp($target_name, '#', 1) === 0) { - $target = id(new PhabricatorBotChannel()) - ->setName($target_name); - } else { - $target = id(new PhabricatorBotUser()) - ->setName($target_name); + $target_name = $matches[1]; + if (strncmp($target_name, '#', 1) === 0) { + $target = id(new PhabricatorBotChannel()) + ->setName($target_name); + } else { + $target = id(new PhabricatorBotUser()) + ->setName($target_name); + } + + return array( + $target, + rtrim($matches[2], "\r\n")); } - - return array( - $target, - rtrim($matches[2], "\r\n")); - } - break; + break; } // By default we assume there is no target, only a body @@ -228,7 +235,7 @@ final class PhabricatorIRCProtocolAdapter } public function __destruct() { - $this->write("QUIT Goodbye.\r\n"); + $this->write("QUIT Goodbye."); fclose($this->socket); } } diff --git a/src/infrastructure/daemon/bot/handler/PhabricatorIRCProtocolHandler.php b/src/infrastructure/daemon/bot/handler/PhabricatorIRCProtocolHandler.php index 023ffc065f..3f3ee28638 100644 --- a/src/infrastructure/daemon/bot/handler/PhabricatorIRCProtocolHandler.php +++ b/src/infrastructure/daemon/bot/handler/PhabricatorIRCProtocolHandler.php @@ -1,41 +1,15 @@ getCommand()) { - case '422': // Error - no MOTD - case '376': // End of MOTD - $nickpass = $this->getConfig('nickpass'); - if ($nickpass) { - $this->writeMessage( - id(new PhabricatorBotMessage()) - ->setCommand('MESSAGE') - ->setTarget('nickserv') - ->setBody("IDENTIFY {$nickpass}")); - } - $join = $this->getConfig('join'); - if (!$join) { - throw new Exception("Not configured to join any channels!"); - } - foreach ($join as $channel) { - $this->writeMessage( - id(new PhabricatorBotMessage()) - ->setCommand('JOIN') - ->setBody($channel)); - } - break; - case 'PING': - $this->writeMessage( - id(new PhabricatorBotMessage()) - ->setCommand('PONG') - ->setBody($message->getBody())); - break; + static $warned; + if (!$warned) { + $warned = true; + phlog("The PhabricatorIRCProtocolHandler has been deprecated."); } }