mls 0.11.3 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/mls.rb +46 -46
- data/lib/mls/{property.rb → attribute.rb} +2 -2
- data/lib/mls/{properties → attributes}/array.rb +1 -1
- data/lib/mls/{properties → attributes}/boolean.rb +1 -1
- data/lib/mls/{properties → attributes}/datetime.rb +1 -1
- data/lib/mls/{properties → attributes}/decimal.rb +1 -1
- data/lib/mls/{properties → attributes}/fixnum.rb +1 -1
- data/lib/mls/{properties → attributes}/hash.rb +1 -1
- data/lib/mls/{properties → attributes}/string.rb +1 -1
- data/lib/mls/factories/listing.rb +3 -3
- data/lib/mls/model.rb +33 -33
- data/lib/mls/models/account.rb +55 -46
- data/lib/mls/models/address.rb +18 -117
- data/lib/mls/models/brokerage.rb +6 -6
- data/lib/mls/models/floorplan.rb +5 -5
- data/lib/mls/models/flyer.rb +5 -5
- data/lib/mls/models/listing.rb +80 -76
- data/lib/mls/models/pdf.rb +4 -4
- data/lib/mls/models/photo.rb +10 -10
- data/lib/mls/models/property.rb +113 -0
- data/lib/mls/models/region.rb +14 -14
- data/lib/mls/models/tour.rb +10 -10
- data/lib/mls/models/video.rb +7 -7
- data/lib/mls/parser.rb +1 -1
- data/lib/mls/resource.rb +15 -15
- data/lib/rdoc/generator/template/42floors/resources/css/github.css +1 -1
- data/lib/rdoc/generator/template/42floors/resources/js/highlight.pack.js +1 -1
- data/lib/rdoc/generator/template/42floors/resources/js/jquery-1.3.2.min.js +1 -1
- data/lib/rdoc/generator/template/42floors/resources/js/jquery-effect.js +6 -6
- data/mls.gemspec +1 -1
- data/test/test_helper.rb +1 -1
- data/test/units/models/test_address.rb +4 -4
- data/test/units/models/test_contact.rb +1 -1
- data/test/units/models/test_listing.rb +4 -4
- data/test/units/test_mls.rb +60 -60
- data/test/units/test_model.rb +3 -3
- data/test/units/test_property.rb +18 -18
- data/test/units/test_resource.rb +1 -1
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7bf2fb1f45061601b3410b8d455f4237ca7a405
|
4
|
+
data.tar.gz: 159126570b0d6925baaa5593b5d911a9f01aba9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10ab6acf77fd576d34863564b5c6d55ee5439f53481473a06bcee79b55239abcca6637a7d1e1f2d3f5ce918d7237229f85a89ef7d7d8000f3ca454285e1fab04
|
7
|
+
data.tar.gz: afc56b84396934752bf50f3d1e6eaf809b7fd1e103588071ad29dec07bae40f2f7dad2cab06f4decbfada145da0b52a54b2a62d00fc9e77d9157a5d471551c46
|
data/lib/mls.rb
CHANGED
@@ -25,7 +25,7 @@ class MLS
|
|
25
25
|
|
26
26
|
attr_reader :url, :user_agent
|
27
27
|
attr_writer :asset_host, :image_host, :agent_profile
|
28
|
-
attr_accessor :api_key, :
|
28
|
+
attr_accessor :api_key, :auth_cookie, :logger
|
29
29
|
|
30
30
|
# Sets the API Token and Host of the MLS Server
|
31
31
|
#
|
@@ -36,12 +36,12 @@ class MLS
|
|
36
36
|
@api_key = CGI.unescape(@url.user)
|
37
37
|
@host, @port = @url.host, @url.port
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
# Sets the user agent so that MLS can distinguish between multiple users
|
41
41
|
# with the same auth
|
42
42
|
def user_agent=(user_agent)
|
43
43
|
@user_agent = user_agent
|
44
|
-
end
|
44
|
+
end
|
45
45
|
|
46
46
|
def logger # TODO: testme
|
47
47
|
@logger ||= default_logger
|
@@ -58,11 +58,11 @@ class MLS
|
|
58
58
|
def asset_host # TODO: testme
|
59
59
|
@asset_host ||= get('/asset_host').body
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
def image_host # TODO: testme
|
63
63
|
raw_image_host % (rand(4))
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def raw_image_host
|
67
67
|
@image_host ||= get('/image_host').body
|
68
68
|
end
|
@@ -73,20 +73,19 @@ class MLS
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def headers # TODO: testme
|
76
|
-
|
76
|
+
{
|
77
77
|
'Content-Type' => 'application/json',
|
78
78
|
'User-Agent' => @user_agent,
|
79
79
|
'X-42Floors-API-Version' => API_VERSION,
|
80
80
|
'X-42Floors-API-Key' => api_key
|
81
81
|
}
|
82
|
-
h['X-42Floors-API-Auth-Key'] = auth_key if auth_key
|
83
|
-
h
|
84
82
|
end
|
85
|
-
|
86
|
-
def
|
83
|
+
|
84
|
+
def prepare_request(req) # TODO: testme
|
87
85
|
headers.each { |k, v| req[k] = v }
|
86
|
+
req['Cookie'] = auth_cookie if auth_cookie
|
88
87
|
end
|
89
|
-
|
88
|
+
|
90
89
|
# Gets to +url+ on the MLS Server. Automatically includes any headers returned
|
91
90
|
# by the MLS#headers function.
|
92
91
|
#
|
@@ -95,7 +94,7 @@ class MLS
|
|
95
94
|
# * +url+ - The +url+ on the server to Get to. This url will automatically
|
96
95
|
# be prefixed with <tt>"/api"</tt>. To get to <tt>"/api/accounts"</tt>
|
97
96
|
# pass <tt>"/accounts"</tt> as +url+
|
98
|
-
# * +params+ - A Hash or Ruby Object that responds to #to_param. The result
|
97
|
+
# * +params+ - A Hash or Ruby Object that responds to #to_param. The result
|
99
98
|
# of this method is appended on the URL as query params
|
100
99
|
# * +valid_response_codes+ - An Array of HTTP response codes that should be
|
101
100
|
# considered accepable and not raise exceptions. For example If you don't
|
@@ -131,13 +130,13 @@ class MLS
|
|
131
130
|
# end
|
132
131
|
def get(url, params={}, *valid_response_codes, &block)
|
133
132
|
params ||= {}
|
134
|
-
|
133
|
+
|
135
134
|
req = Net::HTTP::Get.new("/api#{url}?" + params.to_param)
|
136
|
-
|
135
|
+
prepare_request(req)
|
137
136
|
|
138
137
|
response = connection.request(req)
|
139
138
|
handle_response(response, valid_response_codes)
|
140
|
-
|
139
|
+
|
141
140
|
response.body.force_encoding(Encoding::UTF_8)
|
142
141
|
if block_given?
|
143
142
|
yield(response, response.code.to_i)
|
@@ -145,7 +144,7 @@ class MLS
|
|
145
144
|
response
|
146
145
|
end
|
147
146
|
end
|
148
|
-
|
147
|
+
|
149
148
|
# Puts to +url+ on the MLS Server. Automatically includes any headers returned
|
150
149
|
# by the MLS#headers function.
|
151
150
|
#
|
@@ -190,11 +189,11 @@ class MLS
|
|
190
189
|
# end
|
191
190
|
def put(url, body={}, *valid_response_codes, &block)
|
192
191
|
body ||= {}
|
193
|
-
|
192
|
+
|
194
193
|
req = Net::HTTP::Put.new("/api#{url}")
|
195
194
|
req.body = Yajl::Encoder.encode(body)
|
196
|
-
|
197
|
-
|
195
|
+
prepare_request(req)
|
196
|
+
|
198
197
|
response = connection.request(req)
|
199
198
|
handle_response(response, valid_response_codes)
|
200
199
|
|
@@ -203,8 +202,8 @@ class MLS
|
|
203
202
|
else
|
204
203
|
response
|
205
204
|
end
|
206
|
-
end
|
207
|
-
|
205
|
+
end
|
206
|
+
|
208
207
|
# Posts to +url+ on the MLS Server. Automatically includes any headers returned
|
209
208
|
# by the MLS#headers function.
|
210
209
|
#
|
@@ -249,11 +248,11 @@ class MLS
|
|
249
248
|
# end
|
250
249
|
def post(url, body={}, *valid_response_codes, &block)
|
251
250
|
body ||= {}
|
252
|
-
|
251
|
+
|
253
252
|
req = Net::HTTP::Post.new("/api#{url}")
|
254
253
|
req.body = Yajl::Encoder.encode(body)
|
255
|
-
|
256
|
-
|
254
|
+
prepare_request(req)
|
255
|
+
|
257
256
|
response = connection.request(req)
|
258
257
|
handle_response(response, valid_response_codes)
|
259
258
|
|
@@ -308,11 +307,11 @@ class MLS
|
|
308
307
|
# end
|
309
308
|
def delete(url, body={}, *valid_response_codes, &block)
|
310
309
|
body ||= {}
|
311
|
-
|
310
|
+
|
312
311
|
req = Net::HTTP::Delete.new("/api#{url}")
|
313
312
|
req.body = Yajl::Encoder.encode(body)
|
314
|
-
|
315
|
-
|
313
|
+
prepare_request(req)
|
314
|
+
|
316
315
|
response = connection.request(req)
|
317
316
|
handle_response(response, valid_response_codes)
|
318
317
|
if block_given?
|
@@ -339,13 +338,13 @@ class MLS
|
|
339
338
|
#
|
340
339
|
# #!ruby
|
341
340
|
# MLS.handle_response(<Net::HTTP::Response @code=200>) # => <Net::HTTP::Response @code=200>
|
342
|
-
#
|
341
|
+
#
|
343
342
|
# MLS.handle_response(<Net::HTTP::Response @code=404>) # => raises MLS::Exception::NotFound
|
344
|
-
#
|
343
|
+
#
|
345
344
|
# MLS.handle_response(<Net::HTTP::Response @code=500>) # => raises MLS::Exception
|
346
|
-
#
|
345
|
+
#
|
347
346
|
# MLS.handle_response(<Net::HTTP::Response @code=404>, 404) # => <Net::HTTP::Response @code=404>
|
348
|
-
#
|
347
|
+
#
|
349
348
|
# MLS.handle_response(<Net::HTTP::Response @code=500>, 404, 500) # => <Net::HTTP::Response @code=500>
|
350
349
|
#
|
351
350
|
# MLS.handle_response(<Net::HTTP::Response @code=405>, 300, 400..499) # => <Net::HTTP::Response @code=405>
|
@@ -355,11 +354,11 @@ class MLS
|
|
355
354
|
if response['X-42Floors-API-Version-Deprecated']
|
356
355
|
logger.warn("DEPRECATION WARNING: API v#{API_VERSION} is being phased out")
|
357
356
|
end
|
358
|
-
|
357
|
+
|
359
358
|
code = response.code.to_i
|
360
359
|
valid_response_codes.flatten!
|
361
360
|
valid_response_codes << (200..299)
|
362
|
-
|
361
|
+
|
363
362
|
if !valid_response_codes.detect{|i| i.is_a?(Range) ? i.include?(code) : i == code}
|
364
363
|
case code
|
365
364
|
when 400
|
@@ -376,16 +375,16 @@ class MLS
|
|
376
375
|
raise MLS::Exception, code
|
377
376
|
end
|
378
377
|
end
|
379
|
-
|
378
|
+
|
380
379
|
response
|
381
380
|
end
|
382
|
-
|
381
|
+
|
383
382
|
# Ping the MLS. If everything is configured and operating correctly <tt>"pong"</tt>
|
384
383
|
# will be returned. Otherwise and MLS::Exception should be thrown.
|
385
384
|
#
|
386
385
|
# #!ruby
|
387
386
|
# MLS.ping # => "pong"
|
388
|
-
#
|
387
|
+
#
|
389
388
|
# MLS.ping # raises MLS::Exception::ServiceUnavailable if a 503 is returned
|
390
389
|
def ping # TODO: testme
|
391
390
|
get('/ping').body
|
@@ -405,7 +404,7 @@ class MLS
|
|
405
404
|
def self.method_missing(method, *args, &block) #:nodoc: # TODO: testme
|
406
405
|
instance.__send__(method, *args, &block)
|
407
406
|
end
|
408
|
-
|
407
|
+
|
409
408
|
def self.parse(json) # TODO: testme
|
410
409
|
Yajl::Parser.new(:symbolize_keys => true).parse(json)
|
411
410
|
end
|
@@ -416,21 +415,22 @@ require 'mls/errors'
|
|
416
415
|
require 'mls/resource'
|
417
416
|
require 'mls/parser'
|
418
417
|
|
419
|
-
#
|
420
|
-
require 'mls/
|
421
|
-
require 'mls/
|
422
|
-
require 'mls/
|
423
|
-
require 'mls/
|
424
|
-
require 'mls/
|
425
|
-
require 'mls/
|
426
|
-
require 'mls/
|
427
|
-
require 'mls/
|
418
|
+
# Attributes
|
419
|
+
require 'mls/attribute'
|
420
|
+
require 'mls/attributes/fixnum'
|
421
|
+
require 'mls/attributes/boolean'
|
422
|
+
require 'mls/attributes/decimal'
|
423
|
+
require 'mls/attributes/datetime'
|
424
|
+
require 'mls/attributes/string'
|
425
|
+
require 'mls/attributes/hash'
|
426
|
+
require 'mls/attributes/array'
|
428
427
|
|
429
428
|
# Models
|
430
429
|
require 'mls/model'
|
431
430
|
require 'mls/models/account'
|
432
431
|
require 'mls/models/listing'
|
433
432
|
require 'mls/models/address'
|
433
|
+
require 'mls/models/property'
|
434
434
|
require 'mls/models/photo'
|
435
435
|
require 'mls/models/video'
|
436
436
|
require 'mls/models/pdf'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class MLS::
|
1
|
+
class MLS::Attribute
|
2
2
|
DEFAULT_OPTIONS = { :serialize => :always }
|
3
3
|
|
4
4
|
attr_reader :model, :name, :instance_variable_name, :options, :default
|
@@ -23,7 +23,7 @@ class MLS::Property
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def self.determine_class(type)
|
26
|
-
return type if type < MLS::
|
26
|
+
return type if type < MLS::Attribute
|
27
27
|
find_class(::ActiveSupport::Inflector.demodulize(type))
|
28
28
|
end
|
29
29
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
factory :listing, :class => MLS::Listing do
|
3
3
|
before(:create) { |l|
|
4
|
-
MLS_GEM_CACHE['
|
5
|
-
MLS.
|
4
|
+
MLS_GEM_CACHE['auth_cookie'] = MLS.auth_cookie
|
5
|
+
MLS.auth_cookie = l.account.auth_cookie
|
6
6
|
}
|
7
7
|
after(:create) { |l|
|
8
|
-
MLS.
|
8
|
+
MLS.auth_cookie = MLS_GEM_CACHE['auth_cookie']
|
9
9
|
}
|
10
10
|
|
11
11
|
association :account
|
data/lib/mls/model.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module MLS::Model
|
2
2
|
|
3
3
|
def self.extended(model) #:nodoc:
|
4
|
-
model.instance_variable_set(:@
|
4
|
+
model.instance_variable_set(:@attributes, {})
|
5
5
|
model.instance_variable_set(:@associations, {})
|
6
6
|
end
|
7
7
|
|
@@ -24,34 +24,34 @@ module MLS::Model
|
|
24
24
|
model
|
25
25
|
end
|
26
26
|
|
27
|
-
#
|
27
|
+
# Attributes ===================================================================================================
|
28
28
|
|
29
|
-
def
|
30
|
-
klass = MLS::
|
29
|
+
def attribute(name, type, options = {})
|
30
|
+
klass = MLS::Attribute.determine_class(type)
|
31
31
|
raise NotImplementedError, "#{type} is not supported" unless klass
|
32
32
|
|
33
|
-
|
34
|
-
@
|
35
|
-
@
|
33
|
+
attribute = klass.new(name, options)
|
34
|
+
@attributes[attribute.name] = attribute
|
35
|
+
@attributes_excluded_from_comparison = []
|
36
36
|
|
37
|
-
create_reader_for(
|
38
|
-
create_writer_for(
|
37
|
+
create_reader_for(attribute)
|
38
|
+
create_writer_for(attribute)
|
39
39
|
end
|
40
40
|
|
41
|
-
def exclude_from_comparison(*
|
42
|
-
@
|
41
|
+
def exclude_from_comparison(*attributes)
|
42
|
+
@attributes_excluded_from_comparison |= attributes
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
46
|
-
@
|
45
|
+
def attributes_excluded_from_comparison
|
46
|
+
@attributes_excluded_from_comparison
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
50
|
-
@
|
49
|
+
def attributes
|
50
|
+
@attributes
|
51
51
|
end
|
52
52
|
|
53
|
-
def
|
54
|
-
@
|
53
|
+
def attribute_module
|
54
|
+
@attribute_module ||= begin
|
55
55
|
mod = Module.new
|
56
56
|
class_eval do
|
57
57
|
include mod
|
@@ -60,23 +60,23 @@ module MLS::Model
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def create_reader_for(
|
64
|
-
reader_name =
|
63
|
+
def create_reader_for(attribute)
|
64
|
+
reader_name = attribute.name.to_s
|
65
65
|
boolean_reader_name = "#{reader_name}?"
|
66
|
-
reader_visibility =
|
67
|
-
instance_variable_name =
|
66
|
+
reader_visibility = attribute.reader_visibility
|
67
|
+
instance_variable_name = attribute.instance_variable_name
|
68
68
|
|
69
|
-
|
69
|
+
attribute_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
70
70
|
#{reader_visibility}
|
71
71
|
def #{reader_name}
|
72
72
|
return #{instance_variable_name} if defined?(#{instance_variable_name})
|
73
|
-
|
74
|
-
#{instance_variable_name} =
|
73
|
+
attribute = attributes[:#{reader_name}]
|
74
|
+
#{instance_variable_name} = attribute ? attribute.default : nil
|
75
75
|
end
|
76
76
|
RUBY
|
77
77
|
|
78
|
-
if
|
79
|
-
|
78
|
+
if attribute.kind_of?(MLS::Attribute::Boolean)
|
79
|
+
attribute_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
80
80
|
#{reader_visibility}
|
81
81
|
def #{boolean_reader_name}
|
82
82
|
#{reader_name}
|
@@ -85,17 +85,17 @@ module MLS::Model
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
def create_writer_for(
|
89
|
-
name =
|
88
|
+
def create_writer_for(attribute)
|
89
|
+
name = attribute.name
|
90
90
|
writer_name = "#{name}="
|
91
|
-
writer_visibility =
|
92
|
-
instance_variable_name =
|
91
|
+
writer_visibility = attribute.writer_visibility
|
92
|
+
instance_variable_name = attribute.instance_variable_name
|
93
93
|
|
94
|
-
|
94
|
+
attribute_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
95
95
|
#{writer_visibility}
|
96
96
|
def #{writer_name}(value)
|
97
|
-
|
98
|
-
#{instance_variable_name} =
|
97
|
+
attribute = self.class.attributes[:#{name}]
|
98
|
+
#{instance_variable_name} = attribute.load(value)
|
99
99
|
end
|
100
100
|
RUBY
|
101
101
|
end
|