From 3cadc2eba38aca4dc38db7d8b53232c2a80dae24 Mon Sep 17 00:00:00 2001 From: Adrien Gallou Date: Sun, 25 Aug 2013 00:12:45 +0200 Subject: [PATCH 1/4] add hipchat notifier --- config/ProjectConfiguration.class.php | 2 + config/notifiers.yml.dist | 19 ++ lib/notifiers/HipchatNotifier.class.php | 46 ++++ lib/vendor/HipChat/HipChat.php | 349 ++++++++++++++++++++++++ 4 files changed, 416 insertions(+) create mode 100644 lib/notifiers/HipchatNotifier.class.php create mode 100644 lib/vendor/HipChat/HipChat.php diff --git a/config/ProjectConfiguration.class.php b/config/ProjectConfiguration.class.php index 4f89521..105eee3 100644 --- a/config/ProjectConfiguration.class.php +++ b/config/ProjectConfiguration.class.php @@ -11,6 +11,8 @@ public function setup() $this->enablePlugins('sfGuardPlugin'); $this->enablePlugins('crewLessPlugin'); require_once sfConfig::get('sf_root_dir') . '/lib/vendor/XMPPHP/XMPP.php'; + require_once sfConfig::get('sf_root_dir') . '/lib/vendor/HipChat/HipChat.php'; + $this->dispatcher->connect('context.load_factories', array($this, 'listenLoadFactoriesEvent')); } diff --git a/config/notifiers.yml.dist b/config/notifiers.yml.dist index b12cb07..1a91dcb 100644 --- a/config/notifiers.yml.dist +++ b/config/notifiers.yml.dist @@ -41,4 +41,23 @@ XmppNotifier: server: jabber.yourdomain.com to: team-chatroom@conference.jabber.yourdomain.com type: groupchat +HipchatNotifier: + review-request: + enabled: 1 + message: "New review request for branch %branch%" + add-links: 1 + notify: 0 + color: "purple" + comment: + enabled: 1 + branch_message: "%branch% - %author% : %message%" + file_message: "%branch% - %author% : %message%" + line_message: "%branch% - %author% : %message%" + add-links: 1 + notify: 0 + projects: + 2: + token: "2718a778gavde59a8fa51aa7aze" + room: "developers" + user: "Crew" diff --git a/lib/notifiers/HipchatNotifier.class.php b/lib/notifiers/HipchatNotifier.class.php new file mode 100644 index 0000000..13324ce --- /dev/null +++ b/lib/notifiers/HipchatNotifier.class.php @@ -0,0 +1,46 @@ +getCurrentProjectConfig(); + + $token = $configCurrentProject['token']; + $room = $configCurrentProject['room']; + $user = $configCurrentProject['user']; + + list(,$eventName) = explode('.', $this->name); + $eventConfig = $this->getEventConfig($eventName); + + $notify = isset($eventConfig['notify']) && $eventConfig['notify'] == '1'; + + $color = HipChat\Hipchat::COLOR_YELLOW; + if (isset($eventConfig['color'])) + { + $color = $eventConfig['color']; + } + + $hipChat = new HipChat\HipChat($token); + $hipChat->message_room($room, $user, $message, $notify, $color, HipChat\Hipchat::FORMAT_TEXT); + + return $this; + } + +} diff --git a/lib/vendor/HipChat/HipChat.php b/lib/vendor/HipChat/HipChat.php new file mode 100644 index 0000000..13c55b9 --- /dev/null +++ b/lib/vendor/HipChat/HipChat.php @@ -0,0 +1,349 @@ +api_target = $api_target; + $this->auth_token = $auth_token; + $this->api_version = $api_version; + } + + + ///////////////////////////////////////////////////////////////////////////// + // Room functions + ///////////////////////////////////////////////////////////////////////////// + + /** + * Get information about a room + * + * @see http://api.hipchat.com/docs/api/method/rooms/show + */ + public function get_room($room_id) { + $response = $this->make_request("rooms/show", array( + 'room_id' => $room_id + )); + return $response->room; + } + + /** + * Get list of rooms + * + * @see http://api.hipchat.com/docs/api/method/rooms/list + */ + public function get_rooms() { + $response = $this->make_request('rooms/list'); + return $response->rooms; + } + + /** + * Send a message to a room + * + * @see http://api.hipchat.com/docs/api/method/rooms/message + */ + public function message_room($room_id, $from, $message, $notify = false, + $color = self::COLOR_YELLOW, + $message_format = self::FORMAT_HTML) { + $args = array( + 'room_id' => $room_id, + 'from' => $from, + 'message' => utf8_encode($message), + 'notify' => (int)$notify, + 'color' => $color, + 'message_format' => $message_format + ); + $response = $this->make_request("rooms/message", $args, 'POST'); + return ($response->status == 'sent'); + } + + /** + * Get chat history for a room + * + * @see https://www.hipchat.com/docs/api/method/rooms/history + */ + public function get_rooms_history($room_id, $date = 'recent') { + $response = $this->make_request('rooms/history', array( + 'room_id' => $room_id, + 'date' => $date + )); + return $response->messages; + } + + /** + * Set a room's topic + * + * @see http://api.hipchat.com/docs/api/method/rooms/topic + */ + public function set_room_topic($room_id, $topic, $from = null) { + $args = array( + 'room_id' => $room_id, + 'topic' => utf8_encode($topic), + ); + + if ($from) { + $args['from'] = utf8_encode($from); + } + + $response = $this->make_request("rooms/topic", $args, 'POST'); + return ($response->status == 'ok'); + } + + /** + * Create a room + * + * @see http://api.hipchat.com/docs/api/method/rooms/create + */ + public function create_room($name, $owner_user_id = null, $privacy = null, $topic = null, $guest_access = null) { + $args = array( + 'name' => $name + ); + + if ($owner_user_id) { + $args['owner_user_id'] = $owner_user_id; + } + + if ($privacy) { + $args['privacy'] = $privacy; + } + + if ($topic) { + $args['topic'] = utf8_encode($topic); + } + + if ($guest_access) { + $args['guest_access'] = (int) $guest_access; + } + + // Return the std object + return $this->make_request("rooms/create", $args, 'POST'); + } + + /** + * Delete a room + * + * @see http://api.hipchat.com/docs/api/method/rooms/delete + */ + public function delete_room($room_id){ + $args = array( + 'room_id' => $room_id + ); + + $response = $this->make_request("rooms/delete", $args, 'POST'); + + return ($response->deleted == 'true'); + } + + ///////////////////////////////////////////////////////////////////////////// + // User functions + ///////////////////////////////////////////////////////////////////////////// + + /** + * Get information about a user + * + * @see http://api.hipchat.com/docs/api/method/users/show + */ + public function get_user($user_id) { + $response = $this->make_request("users/show", array( + 'user_id' => $user_id + )); + return $response->user; + } + + /** + * Get list of users + * + * @see http://api.hipchat.com/docs/api/method/users/list + */ + public function get_users() { + $response = $this->make_request('users/list'); + return $response->users; + } + + + ///////////////////////////////////////////////////////////////////////////// + // Helper functions + ///////////////////////////////////////////////////////////////////////////// + + /** + * Performs a curl request + * + * @param $url URL to hit. + * @param $post_data Data to send via POST. Leave null for GET request. + * + * @throws HipChat_Exception + * @return string + */ + public function curl_request($url, $post_data = null) { + + if (is_array($post_data)) { + $post_data = array_map(array($this, "sanitize_curl_parameter"), $post_data); + } + + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 15); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl); + if (is_array($post_data)) { + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + } + $response = curl_exec($ch); + + // make sure we got a real response + if (strlen($response) == 0) { + $errno = curl_errno($ch); + $error = curl_error($ch); + throw new HipChat_Exception(self::STATUS_BAD_RESPONSE, + "CURL error: $errno - $error", $url); + } + + // make sure we got a 200 + $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); + if ($code != self::STATUS_OK) { + throw new HipChat_Exception($code, + "HTTP status code: $code, response=$response", $url); + } + + curl_close($ch); + + return $response; + } + + /** + * Sanitizes the given value as cURL parameter. + * + * The first value may not be a "@". PHP would treat this as a file upload + * + * @link http://www.php.net/manual/en/function.curl-setopt.php CURLOPT_POSTFIELDS + * + * @param string $value + * @return string + */ + private function sanitize_curl_parameter ($value) { + + if ((strlen($value) > 0) && ($value[0] === "@")) { + return substr_replace($value, '@', 0, 1); + } + + return $value; + } + + /** + * Make an API request using curl + * + * @param string $api_method Which API method to hit, like 'rooms/show'. + * @param array $args Data to send. + * @param string $http_method HTTP method (GET or POST). + * + * @throws HipChat_Exception + * @return mixed + */ + public function make_request($api_method, $args = array(), + $http_method = 'GET') { + $args['format'] = 'json'; + $args['auth_token'] = $this->auth_token; + $url = "$this->api_target/$this->api_version/$api_method"; + $post_data = null; + + // add args to url for GET + if ($http_method == 'GET') { + $url .= '?'.http_build_query($args); + } else { + $post_data = $args; + } + + $response = $this->curl_request($url, $post_data); + + // make sure response is valid json + $response = json_decode($response); + if (!$response) { + throw new HipChat_Exception(self::STATUS_BAD_RESPONSE, + "Invalid JSON received: $response", $url); + } + + return $response; + } + + /** + * Enable/disable verify_ssl. + * This is useful when curl spits back ssl verification errors, most likely + * due to outdated SSL CA bundle file on server. If you are able to, update + * that CA bundle. If not, call this method with false for $bool param before + * interacting with the API. + * + * @param bool $bool + * @return bool + * @link http://davidwalsh.name/php-ssl-curl-error + */ + public function set_verify_ssl($bool = true) { + $this->verify_ssl = (bool)$bool; + return $this->verify_ssl; + } + +} + + +class HipChat_Exception extends \Exception { + public function __construct($code, $info, $url) { + $message = "HipChat API error: code=$code, info=$info, url=$url"; + parent::__construct($message, (int)$code); + } +} From 5d86bef4186fdf4086944b1fadf9afde0b1f2ba1 Mon Sep 17 00:00:00 2001 From: Adrien Gallou Date: Sun, 25 Aug 2013 00:13:07 +0200 Subject: [PATCH 2/4] remove namespace from hipchat notifier crew must be compatible with php 5.2 so we removed namespaces from the hipchat notifier. --- lib/notifiers/HipchatNotifier.class.php | 6 +++--- lib/vendor/HipChat/HipChat.php | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/notifiers/HipchatNotifier.class.php b/lib/notifiers/HipchatNotifier.class.php index 13324ce..58a6f5c 100644 --- a/lib/notifiers/HipchatNotifier.class.php +++ b/lib/notifiers/HipchatNotifier.class.php @@ -31,14 +31,14 @@ protected function send($message) $notify = isset($eventConfig['notify']) && $eventConfig['notify'] == '1'; - $color = HipChat\Hipchat::COLOR_YELLOW; + $color = Hipchat::COLOR_YELLOW; if (isset($eventConfig['color'])) { $color = $eventConfig['color']; } - $hipChat = new HipChat\HipChat($token); - $hipChat->message_room($room, $user, $message, $notify, $color, HipChat\Hipchat::FORMAT_TEXT); + $hipChat = new HipChat($token); + $hipChat->message_room($room, $user, $message, $notify, $color, Hipchat::FORMAT_TEXT); return $this; } diff --git a/lib/vendor/HipChat/HipChat.php b/lib/vendor/HipChat/HipChat.php index 13c55b9..71799dc 100644 --- a/lib/vendor/HipChat/HipChat.php +++ b/lib/vendor/HipChat/HipChat.php @@ -1,7 +1,5 @@ Date: Wed, 28 Aug 2013 21:31:52 +0200 Subject: [PATCH 3/4] remove useless empty line --- config/ProjectConfiguration.class.php | 1 - 1 file changed, 1 deletion(-) diff --git a/config/ProjectConfiguration.class.php b/config/ProjectConfiguration.class.php index 105eee3..2de4abe 100644 --- a/config/ProjectConfiguration.class.php +++ b/config/ProjectConfiguration.class.php @@ -13,7 +13,6 @@ public function setup() require_once sfConfig::get('sf_root_dir') . '/lib/vendor/XMPPHP/XMPP.php'; require_once sfConfig::get('sf_root_dir') . '/lib/vendor/HipChat/HipChat.php'; - $this->dispatcher->connect('context.load_factories', array($this, 'listenLoadFactoriesEvent')); } From dd407e46d7fd988e6ce076de9798f190f3d50b70 Mon Sep 17 00:00:00 2001 From: Adrien Gallou Date: Wed, 28 Aug 2013 21:34:31 +0200 Subject: [PATCH 4/4] hipchat notifier is now disabled in the example file --- config/notifiers.yml.dist | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/notifiers.yml.dist b/config/notifiers.yml.dist index 1a91dcb..b2b8525 100644 --- a/config/notifiers.yml.dist +++ b/config/notifiers.yml.dist @@ -43,13 +43,13 @@ XmppNotifier: type: groupchat HipchatNotifier: review-request: - enabled: 1 + enabled: 0 message: "New review request for branch %branch%" add-links: 1 notify: 0 color: "purple" comment: - enabled: 1 + enabled: 0 branch_message: "%branch% - %author% : %message%" file_message: "%branch% - %author% : %message%" line_message: "%branch% - %author% : %message%"