mls 0.11.3 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|