Class: MLS

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/mls.rb

Overview

MLS is a low-level API. It provides basic HTTP #get, #post, #put, and #delete calls to the MLS. It can also provides basic error checking of responses.

Defined Under Namespace

Modules: Model Classes: Account, Address, Exception, Floorplan, Flyer, Listing, PDF, Parser, Photo, Property, Region, Resource, TourRequest, Video

Constant Summary collapse

API_VERSION =
'0.1.0'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#address_amenitiesObject



75
76
77
78
# File 'lib/mls.rb', line 75

def address_amenities
  @address_amenities ||= Yajl::Parser.new(:symbolize_keys => true)
    .parse(MLS.get('/addresses/amenities').body)
end

#api_keyObject

Returns the value of attribute api_key.



28
29
30
# File 'lib/mls.rb', line 28

def api_key
  @api_key
end

#asset_hostObject

provides the asset host, if asset_host is set then it is returned, otherwise it queries the MLS for this configuration.



58
59
60
# File 'lib/mls.rb', line 58

def asset_host # TODO: testme
  @asset_host ||= get('/asset_host').body
end

#auth_keyObject

Returns the value of attribute auth_key.



28
29
30
# File 'lib/mls.rb', line 28

def auth_key
  @auth_key
end

#image_hostObject

TODO: testme



62
63
64
# File 'lib/mls.rb', line 62

def image_host # TODO: testme
  raw_image_host % (rand(4))
end

#listing_amenitiesObject



70
71
72
73
# File 'lib/mls.rb', line 70

def listing_amenities
  @listing_amenities ||= Yajl::Parser.new(:symbolize_keys => true)
    .parse(MLS.get('/listings/amenities').body)
end

#loggerObject

TODO: testme



46
47
48
# File 'lib/mls.rb', line 46

def logger
  @logger
end

#urlObject

Returns the value of attribute url.



26
27
28
# File 'lib/mls.rb', line 26

def url
  @url
end

#user_agentObject

Returns the value of attribute user_agent.



26
27
28
# File 'lib/mls.rb', line 26

def user_agent
  @user_agent
end

Class Method Details

.method_missing(method, *args, &block) ⇒ Object

Delegates all uncauge class method calls to the singleton



408
409
410
# File 'lib/mls.rb', line 408

def self.method_missing(method, *args, &block) #:nodoc:  # TODO: testme
  instance.__send__(method, *args, &block)
end

.parse(json) ⇒ Object

TODO: testme



412
413
414
# File 'lib/mls.rb', line 412

def self.parse(json) # TODO: testme
  Yajl::Parser.new(:symbolize_keys => true).parse(json)
end

Instance Method Details

#add_headers(req) ⇒ Object

TODO: testme



91
92
93
# File 'lib/mls.rb', line 91

def add_headers(req) # TODO: testme
  headers.each { |k, v| req[k] = v }
end

#auth_pingObject

TODO: testme



397
398
399
# File 'lib/mls.rb', line 397

def auth_ping # TODO: testme
  post('/ping').body
end

#connectionObject

Returns the current connection to the MLS or if connection has been made it returns a new connection



52
53
54
# File 'lib/mls.rb', line 52

def connection # TODO: testme
  @connection ||= Net::HTTP.new(@host, @port)
end

#default_loggerObject

TODO: testme



401
402
403
404
405
# File 'lib/mls.rb', line 401

def default_logger # TODO: testme
  logger = Logger.new(STDOUT)
  logger.level = Logger::INFO
  logger
end

#delete(url, body = {}, *valid_response_codes, &block) ⇒ Object

Deletes to url on the MLS Server. Automatically includes any headers returned by the MLS#headers function.

Paramaters
  • url - The url on the server to Post to. This url will automatically be prefixed with "/api". To delete to "/api/accounts" pass "/accounts" as url

  • body - A Ruby object which is converted into JSON and added in the request Body.

  • valid_response_codes - An Array of HTTP response codes that should be considered accepable and not raise exceptions. For example If you don’t want a MLS::Exception::NotFound to be raised when a POST request returns a 404 pass in 404, and the response body will be returned if the status code is a 404 as it does if the status code is in the 200..299 rage. Status codes in the 200..299 range are always considred acceptable

Return Value

Returns the return value of the &block if given, otherwise the response object

Examples:

#!ruby
MLS.delete('/example') # => #<Net::HTTP::Response>

MLS.delete('/example', {:body => 'stuff'}) # => #<Net::HTTP::Response>

MLS.delete('/404') # => raises MLS::Exception::NotFound

MLS.delete('/404', nil, 404, 450..499) # => #<Net::HTTP::Response>

MLS.delete('/404', nil, [404, 450..499]) # => #<Net::HTTP::Response>

MLS.delete('/404', nil, 404) # => #<Net::HTTP::Response>

# this will still raise an exception if the response_code is not valid
# and the block will not be called
MLS.delete('/act') do |response, response_code|
  # ...
end


312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/mls.rb', line 312

def delete(url, body={}, *valid_response_codes, &block)
  body ||= {}
  
  req = Net::HTTP::Delete.new("/api#{url}")
  req.body = Yajl::Encoder.encode(body)
  add_headers(req)
  
  response = connection.request(req)
  handle_response(response, valid_response_codes)
  if block_given?
    yield(response, response.code.to_i)
  else
    response
  end
end

#get(url, params = {}, *valid_response_codes, &block) ⇒ Object

Gets to url on the MLS Server. Automatically includes any headers returned by the MLS#headers function.

Paramaters
  • url - The url on the server to Get to. This url will automatically be prefixed with "/api". To get to "/api/accounts" pass "/accounts" as url

  • params - A Hash or Ruby Object that responds to #to_param. The result of this method is appended on the URL as query params

  • valid_response_codes - An Array of HTTP response codes that should be considered accepable and not raise exceptions. For example If you don’t want a MLS::Exception::NotFound to be raised when a GET request returns a 404 pass in 404, and the response body will be returned if the status code is a 404 as it does if the status code is in the 200..299 rage. Status codes in the 200..299 range are always considred acceptable

Return Value

Returns the return value of the &block if given, otherwise the response object

Examples:

#!ruby
MLS.get('/example') # => #<Net::HTTP::Response>

MLS.get('/example', {:body => 'stuff'}) # => #<Net::HTTP::Response>

MLS.get('/404') # => raises MLS::Exception::NotFound

MLS.get('/404', nil, 404, 450..499) # => #<Net::HTTP::Response>

MLS.get('/404', nil, [404, 450..499]) # => #<Net::HTTP::Response>

MLS.get('/404', nil, 404) # => #<Net::HTTP::Response>

# this will still raise an exception if the response_code is not valid
# and the block will not be called
MLS.get('/act') do |response, response_code|
  # ...
end


137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/mls.rb', line 137

def get(url, params={}, *valid_response_codes, &block)
  params ||= {}
  
  req = Net::HTTP::Get.new("/api#{url}?" + params.to_param)
  add_headers(req)

  response = connection.request(req)
  handle_response(response, valid_response_codes)
  if block_given?
    yield(response, response.code.to_i)
  else
    response
  end
end

#handle_response(response, *valid_response_codes) ⇒ Object

Raise an MLS::Exception based on the response_code, unless the response_code is include in the valid_response_codes Array

Paramaters
  • response - The Net::HTTP::Response object

  • valid_response_codes - An Array, Integer, or Range. If it’s Array the Array can include both Integers or Ranges.

Return Value

If an exception is not raised the response is returned

Examples:

#!ruby
MLS.handle_response(<Net::HTTP::Response @code=200>) # => <Net::HTTP::Response @code=200>

MLS.handle_response(<Net::HTTP::Response @code=404>) # => raises MLS::Exception::NotFound

MLS.handle_response(<Net::HTTP::Response @code=500>) # => raises MLS::Exception

MLS.handle_response(<Net::HTTP::Response @code=404>, 404) # => <Net::HTTP::Response @code=404>

MLS.handle_response(<Net::HTTP::Response @code=500>, 404, 500) # => <Net::HTTP::Response @code=500>

MLS.handle_response(<Net::HTTP::Response @code=405>, 300, 400..499) # => <Net::HTTP::Response @code=405>

MLS.handle_response(<Net::HTTP::Response @code=405>, [300, 400..499]) # => <Net::HTTP::Response @code=405>


357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/mls.rb', line 357

def handle_response(response, *valid_response_codes)
  if response['X-42Floors-API-Version-Deprecated']
    logger.warn("DEPRECATION WARNING: API v#{API_VERSION} is being phased out")
  end
  
  code = response.code.to_i
  valid_response_codes.flatten!
  valid_response_codes << (200..299)
  
  if !valid_response_codes.detect{|i| i.is_a?(Range) ? i.include?(code) : i == code}
    case code
    when 400
      raise MLS::Exception::BadRequest, response.body
    when 401
      raise MLS::Exception::Unauthorized, response.body
    when 404, 410
      raise MLS::Exception::NotFound
    when 422
      raise MLS::Exception::ApiVersionUnsupported, response.body
    when 503
      raise MLS::Exception::ServiceUnavailable, response.body
    when 300..599
      raise MLS::Exception, code
    end
  end
  
  response
end

#headersObject

TODO: testme



80
81
82
83
84
85
86
87
88
89
# File 'lib/mls.rb', line 80

def headers # TODO: testme
  h = {
    'Content-Type' => 'application/json',
    'User-Agent' => @user_agent,
    'X-42Floors-API-Version' => API_VERSION,
    'X-42Floors-API-Key' => api_key
  }
  h['X-42Floors-API-Auth-Key'] = auth_key if auth_key
  h
end

#pingObject

Ping the MLS. If everything is configured and operating correctly "pong" will be returned. Otherwise and MLS::Exception should be thrown.

#!ruby
MLS.ping # => "pong"

MLS.ping # raises MLS::Exception::ServiceUnavailable if a 503 is returned


393
394
395
# File 'lib/mls.rb', line 393

def ping # TODO: testme
  get('/ping').body
end

#post(url, body = {}, *valid_response_codes, &block) ⇒ Object

Posts to url on the MLS Server. Automatically includes any headers returned by the MLS#headers function.

Paramaters
  • url - The url on the server to Post to. This url will automatically be prefixed with "/api". To post to "/api/accounts" pass "/accounts" as url

  • body - A Ruby object which is converted into JSON and added in the request Body.

  • valid_response_codes - An Array of HTTP response codes that should be considered accepable and not raise exceptions. For example If you don’t want a MLS::Exception::NotFound to be raised when a POST request returns a 404 pass in 404, and the response body will be returned if the status code is a 404 as it does if the status code is in the 200..299 rage. Status codes in the 200..299 range are always considred acceptable

Return Value

Returns the return value of the &block if given, otherwise the response object

Examples:

#!ruby
MLS.post('/example') # => #<Net::HTTP::Response>

MLS.post('/example', {:body => 'stuff'}) # => #<Net::HTTP::Response>

MLS.post('/404') # => raises MLS::Exception::NotFound

MLS.post('/404', nil, 404, 450..499) # => #<Net::HTTP::Response>

MLS.post('/404', nil, [404, 450..499]) # => #<Net::HTTP::Response>

MLS.post('/404', nil, 404) # => #<Net::HTTP::Response>

# this will still raise an exception if the response_code is not valid
# and the block will not be called
MLS.post('/act') do |response, response_code|
  # ...
end


253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/mls.rb', line 253

def post(url, body={}, *valid_response_codes, &block)
  body ||= {}
  
  req = Net::HTTP::Post.new("/api#{url}")
  req.body = Yajl::Encoder.encode(body)
  add_headers(req)
  
  response = connection.request(req)
  handle_response(response, valid_response_codes)

  if block_given?
    yield(response, response.code.to_i)
  else
    response
  end
end

#put(url, body = {}, *valid_response_codes, &block) ⇒ Object

Puts to url on the MLS Server. Automatically includes any headers returned by the MLS#headers function.

Paramaters
  • url - The url on the server to Put to. This url will automatically be prefixed with "/api". To put to "/api/accounts" pass "/accounts" as url

  • body - A Ruby object which is converted into JSON and added in the request Body.

  • valid_response_codes - An Array of HTTP response codes that should be considered accepable and not raise exceptions. For example If you don’t want a MLS::Exception::NotFound to be raised when a PUT request returns a 404 pass in 404, and the response body will be returned if the status code is a 404 as it does if the status code is in the 200..299 rage. Status codes in the 200..299 range are always considred acceptable

Return Value

Returns the return value of the &block if given, otherwise the response object

Examples:

#!ruby
MLS.put('/example') # => #<Net::HTTP::Response>

MLS.put('/example', {:body => 'stuff'}) # => #<Net::HTTP::Response>

MLS.put('/404') # => raises MLS::Exception::NotFound

MLS.put('/404', nil, 404, 450..499) # => #<Net::HTTP::Response>

MLS.put('/404', nil, [404, 450..499]) # => #<Net::HTTP::Response>

MLS.put('/404', nil, 404) # => #<Net::HTTP::Response>

# this will still raise an exception if the response_code is not valid
# and the block will not be called
MLS.put('/act') do |response, response_code|
  # ...
end


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/mls.rb', line 194

def put(url, body={}, *valid_response_codes, &block)
  body ||= {}
  
  req = Net::HTTP::Put.new("/api#{url}")
  req.body = Yajl::Encoder.encode(body)
  add_headers(req)
  
  response = connection.request(req)
  handle_response(response, valid_response_codes)

  if block_given?
    yield(response, response.code.to_i)
  else
    response
  end
end

#raw_image_hostObject



66
67
68
# File 'lib/mls.rb', line 66

def raw_image_host
  @image_host ||= get('/image_host').body
end