hipchat 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b54a53da40893dd5e1fbd4d0fafa3f75f00c685
4
- data.tar.gz: c5f30c699dda1135934c4085faeefd3c6667a837
3
+ metadata.gz: d6e9ee49fd12948084e362a20620cb7331e13f41
4
+ data.tar.gz: d1b658a816e7f42d34c6a5cdbf3f3c51e3f43542
5
5
  SHA512:
6
- metadata.gz: a61559bdf4536909fcd9857a0f2afed9eb4ee2baf96cbe69b76a0dd4dce36f6888b7f089759189bce1a13848973c71d42cb49659f26fb75c233a9bbe1e9dbbb0
7
- data.tar.gz: cf8f7bed717b1b5854d17b4297d680e324f131ac5d32f1ef8a509ad4fb04882a687fbb6e99156a6edf4530025b7459af5bcb6ccace87f34e5503e7295909c099
6
+ metadata.gz: 7de04454a535bf911c40aa3d81a717ef80a0fd7996ed5272f80b0aeea5414e6c345b31455ecfeba394df3dfe9fa5ef41e6797d3bc0d578cc27ad859abb9cbcd4
7
+ data.tar.gz: 6e003b0651748e0507d18a57fd0b1acf50bd7ce9ecd3a8c24353ec6eaa4f7da24714e7eb626227d9ef88cdcc4e3fec57fe5b32dc5da18fda607d0d7b79e79040
data/hipchat.gemspec CHANGED
@@ -21,8 +21,9 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = '>= 1.9.3'
22
22
 
23
23
  spec.add_dependency "httparty"
24
+ spec.add_dependency "mimemagic"
24
25
 
25
- spec.add_development_dependency "rspec", "~> 2.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
26
27
  spec.add_development_dependency "rr"
27
28
  spec.add_development_dependency "bundler", "~> 1.3"
28
29
  spec.add_development_dependency "rake"
data/lib/hipchat.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  require 'hipchat/railtie' if defined?(Rails::Railtie)
2
- require "hipchat/version"
2
+ require 'hipchat/version'
3
3
 
4
4
  module HipChat
5
+ require 'hipchat/api_version'
5
6
  require 'hipchat/errors'
7
+ require 'hipchat/file_helper'
6
8
  require 'hipchat/room'
7
9
  require 'hipchat/client'
8
10
  require 'hipchat/user'
@@ -58,17 +58,24 @@ module HipChat
58
58
 
59
59
  def users_config
60
60
  {
61
- :url => '/user',
62
- :data_key => 'items'
63
- }
61
+ 'v1' => {
62
+ :url => '/users/list',
63
+ :data_key => 'users'
64
+ },
65
+ 'v2' => {
66
+ :url => '/user',
67
+ :data_key => 'items'
68
+ }
69
+ }[version]
64
70
  end
65
71
  end
66
72
 
67
73
  class Room < ApiVersion
68
74
 
69
75
  def initialize(options = {})
70
- @room_id = options[:room_id]
71
76
  @version = options[:api_version]
77
+ options[:room_id] ||= options[get_id_attribute]
78
+ @room_id = options[:room_id]
72
79
  if @version.eql?('v1')
73
80
  @base_uri = "#{options[:server_url]}/v1/rooms"
74
81
  @headers = {'Accept' => 'application/json',
@@ -82,17 +89,26 @@ module HipChat
82
89
 
83
90
  attr_reader :version, :base_uri, :room_id, :headers
84
91
 
92
+ def get_id_attribute
93
+ version.eql?('v1') ? 'room_id' : 'id'
94
+ end
95
+
85
96
  def get_room_config
86
97
  {
98
+ 'v1' => {
99
+ :url => URI::escape('/show'),
100
+ :query_params => { :room_id => room_id }
101
+ },
87
102
  'v2' => {
88
- :url => URI::escape("/#{room_id}")
103
+ :url => URI::escape("/#{room_id}"),
104
+ :query_params => { }
89
105
  }
90
106
  }[version]
91
107
  end
92
108
 
93
109
  def update_room_config
94
110
  {
95
- "v2" => {
111
+ 'v2' => {
96
112
  :url => URI::escape("/#{room_id}"),
97
113
  :method => :put,
98
114
  :body_format => :to_json
@@ -122,6 +138,15 @@ module HipChat
122
138
  }[version]
123
139
  end
124
140
 
141
+ def send_file_config
142
+ {
143
+ 'v2' => {
144
+ :url => URI::escape("/#{room_id}/share/file"),
145
+ :body_format => :to_json
146
+ }
147
+ }[version]
148
+ end
149
+
125
150
  def topic_config
126
151
  {
127
152
  'v1' => {
@@ -159,29 +184,67 @@ module HipChat
159
184
 
160
185
  class User
161
186
 
162
- def initialize(user_id, options)
163
- @user_id = user_id
164
- raise InvalidApiVersion, "user API calls invalid for API v1" if ! options[:api_version].eql?('v2')
165
- @base_uri = "#{options[:server_url]}/v2/user"
166
- @headers = {'Accept' => 'application/json',
167
- 'Content-Type' => 'application/json'}
187
+ def initialize(options)
188
+ @version = options[:api_version]
189
+ options[:user_id] ||= options[get_id_attribute]
190
+ @user_id = options[:user_id]
191
+ if @version.eql?('v1')
192
+ @base_uri = "#{options[:server_url]}/v1/users"
193
+ @headers = {'Accept' => 'application/json',
194
+ 'Content-Type' => 'application/x-www-form-urlencoded'}
195
+ else
196
+ @base_uri = "#{options[:server_url]}/v2/user"
197
+ @headers = {'Accept' => 'application/json',
198
+ 'Content-Type' => 'application/json'}
199
+ end
168
200
  end
169
201
 
170
202
  attr_reader :version, :base_uri, :user_id, :headers
171
203
 
204
+ def get_id_attribute
205
+ version.eql?('v1') ? 'user_id' : 'id'
206
+ end
207
+
172
208
  def send_config
209
+ raise InvalidApiVersion, 'This functionality is not supported in API v1' unless version.eql?('v2')
210
+
173
211
  {
174
212
  :url => URI::escape("/#{user_id}/message"),
175
213
  :body_format => :to_json
176
214
  }
177
215
  end
178
216
 
179
- def view_config
217
+ def send_file_config
180
218
  {
181
- :url => URI::escape("/#{user_id}"),
219
+ :url => URI::escape("/#{user_id}/share/file"),
182
220
  :body_format => :to_json
183
221
  }
184
222
  end
223
+
224
+ def view_config
225
+ {
226
+ 'v1' => {
227
+ :url => URI::escape('/show'),
228
+ :body_format => :to_json,
229
+ :query_params => { :user_id => user_id }
230
+ },
231
+ 'v2' => {
232
+ :url => URI::escape("/#{user_id}"),
233
+ :body_format => :to_json,
234
+ :query_params => {}
235
+ }
236
+ }[version]
237
+ end
238
+
239
+ def history_config
240
+ raise InvalidApiVersion, 'This functionality is not supported in API v1' unless version.eql?('v2')
241
+
242
+ {
243
+ :url => URI::escape("/#{user_id}/history/latest"),
244
+ :body_format => :to_json,
245
+ :allowed_params => [:'max-results', :timezone, :'not-before']
246
+ }
247
+ end
185
248
  end
186
249
  end
187
250
  end
@@ -25,6 +25,8 @@ namespace :hipchat do
25
25
  end
26
26
 
27
27
  def send_message(message, options)
28
+ return unless options[:notify]
29
+
28
30
  hipchat_token = fetch(:hipchat_token)
29
31
  hipchat_room_name = fetch(:hipchat_room_name)
30
32
  hipchat_options = fetch(:hipchat_options, {})
@@ -42,7 +42,7 @@ Capistrano::Configuration.instance(:must_exist).load do
42
42
  if fetch(:hipchat_commit_log, false)
43
43
  logs = commit_logs
44
44
  unless logs.empty?
45
- send(logs.join("\n"), send_options)
45
+ send(logs.join(commit_log_line_separator), send_options)
46
46
  end
47
47
  end
48
48
  send("#{human} finished deploying #{deployment_name} to #{environment_string}#{fetch(:hipchat_with_migrations, '')}.", send_options)
@@ -128,6 +128,10 @@ Capistrano::Configuration.instance(:must_exist).load do
128
128
  def env
129
129
  fetch(:hipchat_env, fetch(:rack_env, fetch(:rails_env, "production")))
130
130
  end
131
+
132
+ def commit_log_line_separator
133
+ message_format == "html" ? "<br/>" : "\n"
134
+ end
131
135
  end
132
136
 
133
137
  def commit_logs
data/lib/hipchat/chef.rb CHANGED
@@ -15,20 +15,21 @@ require 'hipchat'
15
15
  module HipChat
16
16
  class NotifyRoom < Chef::Handler
17
17
 
18
- def initialize(api_token, room_name, options={}, msg_options={}, notify_users=false, report_success=false, excluded_envs=[], msg_prefix='')
18
+ def initialize(api_token, room_name, options={})
19
+ defaults = { hipchat_options: {}, msg_options: {}, excluded_envs: [], msg_prefix: ''}
20
+ options = defaults.merge(options)
19
21
  @api_token = api_token
20
22
  @room_name = room_name
21
- @options = options
22
- @report_success = report_success
23
- @msg_options = msg_options
24
- @msg_options[:notify] = notify_users
25
- @excluded_envs = excluded_envs
23
+ @hipchat_options = options[:hipchat_options]
24
+ @msg_options = options[:msg_options]
25
+ @msg_prefix = options[:msg_prefix]
26
+ @excluded_envs = options[:excluded_envs]
26
27
  end
27
28
 
28
29
  def report
29
30
  unless @excluded_envs.include?(node.chef_environment)
30
31
  msg = if run_status.failed? then "Failure on \"#{node.name}\" (\"#{node.chef_environment}\" env): #{run_status.formatted_exception}"
31
- elsif run_status.success? && @report_success
32
+ elsif run_status.success? && @msg_options[:notify]
32
33
  "Chef run on \"#{node.name}\" completed in #{run_status.elapsed_time.round(2)} seconds"
33
34
  else nil
34
35
  end
@@ -38,8 +39,8 @@ module HipChat
38
39
  end
39
40
 
40
41
  if msg
41
- client = HipChat::Client.new(@api_token, @options)
42
- client[@room_name].send('Chef', [msg_prefix, msg].join(' '), @msg_options)
42
+ client = HipChat::Client.new(@api_token, @hipchat_options)
43
+ client[@room_name].send('Chef', [@msg_prefix, msg].join(' '), @msg_options)
43
44
  end
44
45
  end
45
46
  end
@@ -1,5 +1,3 @@
1
- require 'hipchat/api_version'
2
-
3
1
  module HipChat
4
2
 
5
3
  class Client
@@ -23,12 +21,12 @@ module HipChat
23
21
  end
24
22
 
25
23
  def [](name)
26
- Room.new(@token, { room_id: name }.merge(@options))
24
+ HipChat::Room.new(@token, { room_id: name, :api_version => @api_version, :server_url => @options[:server_url] })
27
25
  end
28
26
 
29
27
  def create_room(name, options={})
30
28
  if @api.version == 'v1' && options[:owner_user_id].nil?
31
- raise RoomMissingOwnerUserId, "V1 API Requires owner_user_id"
29
+ raise RoomMissingOwnerUserId, 'V1 API Requires owner_user_id'
32
30
  end
33
31
 
34
32
  if name.length > 50
@@ -52,14 +50,14 @@ module HipChat
52
50
  when 400
53
51
  raise UnknownRoom, "Error: #{response.message}"
54
52
  when 401
55
- raise Unauthorized, "Access denied"
53
+ raise Unauthorized, 'Access denied'
56
54
  else
57
55
  raise UnknownResponseCode, "Unexpected error #{response.code}"
58
56
  end
59
57
  end
60
58
 
61
59
  def user(name)
62
- User.new(@token, { :user_id => name }.merge(@options))
60
+ HipChat::User.new(@token, { :user_id => name, :api_version => @api_version, :server_url => @options[:server_url] })
63
61
  end
64
62
 
65
63
  def users
@@ -97,7 +95,7 @@ module HipChat
97
95
  case response.code
98
96
  when 200
99
97
  response[@api.rooms_config[:data_key]].map do |r|
100
- Room.new(@token, r.merge(:api_version => @api_version, :room_id => r['id'], :server_url => @options[:server_url]))
98
+ HipChat::Room.new(@token, r.merge(:api_version => @api_version, :server_url => @options[:server_url]))
101
99
  end
102
100
  else
103
101
  raise UnknownResponseCode, "Unexpected #{response.code} for room"
@@ -114,8 +112,8 @@ module HipChat
114
112
  )
115
113
  case response.code
116
114
  when 200
117
- response[@api.users_config[:data_key]].map do |r|
118
- User.new(@token, r.merge(:api_version => @api_version, :user_id => r['id']))
115
+ response[@api.users_config[:data_key]].map do |u|
116
+ HipChat::User.new(@token, u.merge(:api_version => @api_version, :server_url => @options[:server_url]))
119
117
  end
120
118
  else
121
119
  raise UnknownResponseCode, "Unexpected #{response.code} for user"
@@ -0,0 +1,42 @@
1
+ require 'mimemagic'
2
+
3
+ module HipChat
4
+ module FileHelper
5
+ BOUNDARY = "sendfileboundary"
6
+
7
+ private
8
+
9
+ #
10
+ # Builds a multipart file body for the api.
11
+ #
12
+ # message - a message to attach
13
+ # file - a File instance
14
+ def file_body(message, file)
15
+ file_name = File.basename(file.path)
16
+ mime_type = MimeMagic.by_path(file_name)
17
+ file_content = Base64.encode64(file.read)
18
+
19
+ body = ["--#{BOUNDARY}"]
20
+ body << 'Content-Type: application/json; charset=UTF-8'
21
+ body << 'Content-Disposition: attachment; name="metadata"'
22
+ body << ''
23
+ body << message
24
+ body << "--#{BOUNDARY}"
25
+ body << "Content-Type: #{mime_type}; charset=UTF-8"
26
+ body << 'Content-Transfer-Encoding: base64'
27
+ body << %{Content-Disposition: attachment; name="file"; filename="#{file_name}"}
28
+ body << ''
29
+ body << file_content
30
+ body << "--#{BOUNDARY}--"
31
+ body.join("\n")
32
+ end
33
+
34
+ #
35
+ # Appends headers require for the multipart body.
36
+ #
37
+ # headers - a base headers hash
38
+ def file_body_headers(headers)
39
+ headers.merge('Content-Type' => "multipart/related; boundary=#{BOUNDARY}")
40
+ end
41
+ end
42
+ end
@@ -42,8 +42,8 @@ namespace :hipchat do
42
42
 
43
43
  client = HipChat::Client.new(options[:token], options)
44
44
 
45
- options[:room].each do |r|
46
- client[options[r]].send(options[:user], options[:message], { :color => options[:color], :notify => options[:notify] })
45
+ options[:room].each do |r|
46
+ client[r].send(options[:user], options[:message], { :color => options[:color], :notify => options[:notify] })
47
47
  end
48
48
  end
49
49
  end
data/lib/hipchat/room.rb CHANGED
@@ -5,6 +5,7 @@ module HipChat
5
5
 
6
6
  class Room < OpenStruct
7
7
  include HTTParty
8
+ include FileHelper
8
9
 
9
10
  format :json
10
11
 
@@ -18,7 +19,7 @@ module HipChat
18
19
  # Retrieve data for this room
19
20
  def get_room
20
21
  response = self.class.get(@api.get_room_config[:url],
21
- :query => {:auth_token => @token },
22
+ :query => {:auth_token => @token }.merge(@api.get_room_config[:query_params]),
22
23
  :headers => @api.headers
23
24
  )
24
25
 
@@ -37,7 +38,7 @@ module HipChat
37
38
  # Update a room
38
39
  def update_room(options = {})
39
40
  options = {
40
- :privacy => "public",
41
+ :privacy => 'public',
41
42
  :is_archived => false,
42
43
  :is_guest_accessible => false
43
44
  }.merge symbolize(options)
@@ -54,8 +55,6 @@ module HipChat
54
55
  }.to_json,
55
56
  :headers => @api.headers)
56
57
 
57
- puts response.body
58
-
59
58
  case response.code
60
59
  when 200, 204; true
61
60
  when 404
@@ -68,7 +67,7 @@ module HipChat
68
67
  end
69
68
 
70
69
  # Invite user to this room
71
- def invite(user, reason="")
70
+ def invite(user, reason='')
72
71
  response = self.class.post(@api.invite_config[:url]+"/#{user}",
73
72
  :query => { :auth_token => @token },
74
73
  :body => {
@@ -112,7 +111,7 @@ module HipChat
112
111
  raise UsernameTooLong, "Username #{from} is `#{from.length} characters long. Limit is 15'"
113
112
  end
114
113
  options = if options_or_notify == true or options_or_notify == false
115
- warn "DEPRECATED: Specify notify flag as an option (e.g., :notify => true)"
114
+ warn 'DEPRECATED: Specify notify flag as an option (e.g., :notify => true)'
116
115
  { :notify => options_or_notify }
117
116
  else
118
117
  options_or_notify || {}
@@ -144,6 +143,40 @@ module HipChat
144
143
  end
145
144
  end
146
145
 
146
+ # Send a file to this room.
147
+ #
148
+ # Usage:
149
+ #
150
+ # # Default
151
+ # send_file 'nickname', 'some message', File.open("/path/to/file")
152
+ def send_file(from, message, file)
153
+ if from.length > 15
154
+ raise UsernameTooLong, "Username #{from} is `#{from.length} characters long. Limit is 15'"
155
+ end
156
+
157
+ response = self.class.post(@api.send_file_config[:url],
158
+ :query => { :auth_token => @token },
159
+ :body => file_body(
160
+ {
161
+ :room_id => room_id,
162
+ :from => from,
163
+ :message => message,
164
+ }.send(@api.send_config[:body_format]), file
165
+ ),
166
+ :headers => file_body_headers(@api.headers)
167
+ )
168
+
169
+ case response.code
170
+ when 200, 204; true
171
+ when 404
172
+ raise UnknownRoom, "Unknown room: `#{room_id}'"
173
+ when 401
174
+ raise Unauthorized, "Access denied to room `#{room_id}'"
175
+ else
176
+ raise UnknownResponseCode, "Unexpected #{response.code} for room `#{room_id}'"
177
+ end
178
+ end
179
+
147
180
  # Change this room's topic
148
181
  #
149
182
  # Usage:
@@ -197,7 +230,12 @@ module HipChat
197
230
  # (default "JSON")
198
231
  def history(options = {})
199
232
 
200
- options = { :date => 'recent', :timezone => 'UTC', :format => 'JSON' }.merge options
233
+ options = {
234
+ :date => 'recent',
235
+ :timezone => 'UTC',
236
+ :format => 'JSON',
237
+ :'max-results' => 100
238
+ }.merge options
201
239
 
202
240
  response = self.class.get(@api.history_config[:url],
203
241
  :query => {
@@ -205,7 +243,8 @@ module HipChat
205
243
  :date => options[:date],
206
244
  :timezone => options[:timezone],
207
245
  :format => options[:format],
208
- :auth_token => @token,
246
+ :'max-results' => options[:'max-results'],
247
+ :auth_token => @token
209
248
  },
210
249
  :headers => @api.headers
211
250
  )
@@ -253,8 +292,8 @@ module HipChat
253
292
  return obj.reduce({}) do |memo, (k, v)|
254
293
  memo.tap { |m| m[k.to_sym] = symbolize(v) }
255
294
  end if obj.is_a? Hash
256
-
257
- return obj.reduce([]) do |memo, v|
295
+
296
+ return obj.reduce([]) do |memo, v|
258
297
  memo << symbolize(v); memo
259
298
  end if obj.is_a? Array
260
299
  obj