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, Resource, Tour, 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



80
81
82
83
# File 'lib/mls.rb', line 80

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

#agent_profile(id) ⇒ Object



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

def agent_profile(id)
  @agent_profile = Yajl::Parser.new(:symbolize_keys => true)
    .parse(MLS.get("/agents/#{id}").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



415
416
417
# File 'lib/mls.rb', line 415

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

.parse(json) ⇒ Object

TODO: testme



419
420
421
# File 'lib/mls.rb', line 419

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

Instance Method Details

#add_headers(req) ⇒ Object

TODO: testme



96
97
98
# File 'lib/mls.rb', line 96

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

#auth_pingObject

TODO: testme



404
405
406
# File 'lib/mls.rb', line 404

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



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

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


319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/mls.rb', line 319

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


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/mls.rb', line 142

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)
  
  response.body.force_encoding(Encoding::UTF_8)
  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>


364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/mls.rb', line 364

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



85
86
87
88
89
90
91
92
93
94
# File 'lib/mls.rb', line 85

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


400
401
402
# File 'lib/mls.rb', line 400

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


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/mls.rb', line 260

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


201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/mls.rb', line 201

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