mls 0.14.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Rakefile +6 -6
- data/lib/mls.rb +73 -427
- data/lib/mls/account.rb +15 -0
- data/lib/mls/address.rb +4 -0
- data/lib/mls/agency.rb +6 -0
- data/lib/mls/brokerage.rb +7 -0
- data/lib/mls/coworking_space.rb +5 -0
- data/lib/mls/floorplan.rb +11 -0
- data/lib/mls/flyer.rb +11 -0
- data/lib/mls/lease.rb +2 -0
- data/lib/mls/listing.rb +135 -0
- data/lib/mls/locality.rb +6 -0
- data/lib/mls/photo.rb +18 -0
- data/lib/mls/property.rb +24 -0
- data/lib/mls/region.rb +13 -0
- data/lib/mls/sale.rb +2 -0
- data/lib/mls/space.rb +3 -0
- data/lib/mls/sublease.rb +2 -0
- data/lib/mls/use.rb +25 -0
- data/mls.gemspec +11 -15
- data/test/mls/attribute_test.rb +55 -0
- data/test/mls/resource_test.rb +31 -0
- data/test/mls_test.rb +27 -0
- data/test/test_helper.rb +26 -27
- metadata +43 -75
- data/lib/mls/attribute.rb +0 -44
- data/lib/mls/attributes/array.rb +0 -11
- data/lib/mls/attributes/boolean.rb +0 -9
- data/lib/mls/attributes/datetime.rb +0 -25
- data/lib/mls/attributes/decimal.rb +0 -21
- data/lib/mls/attributes/fixnum.rb +0 -16
- data/lib/mls/attributes/hash.rb +0 -15
- data/lib/mls/attributes/string.rb +0 -15
- data/lib/mls/errors.rb +0 -29
- data/lib/mls/factories/account.rb +0 -34
- data/lib/mls/factories/address.rb +0 -16
- data/lib/mls/factories/listing.rb +0 -29
- data/lib/mls/factories_helper.rb +0 -7
- data/lib/mls/model.rb +0 -125
- data/lib/mls/models/account.rb +0 -174
- data/lib/mls/models/address.rb +0 -58
- data/lib/mls/models/brokerage.rb +0 -31
- data/lib/mls/models/floorplan.rb +0 -45
- data/lib/mls/models/flyer.rb +0 -45
- data/lib/mls/models/listing.rb +0 -394
- data/lib/mls/models/pdf.rb +0 -15
- data/lib/mls/models/photo.rb +0 -40
- data/lib/mls/models/property.rb +0 -114
- data/lib/mls/models/region.rb +0 -56
- data/lib/mls/models/tour.rb +0 -54
- data/lib/mls/models/video.rb +0 -18
- data/lib/mls/parser.rb +0 -74
- data/lib/mls/resource.rb +0 -99
- data/lib/rdoc/generator/template/42floors/_context.rhtml +0 -209
- data/lib/rdoc/generator/template/42floors/_head.rhtml +0 -7
- data/lib/rdoc/generator/template/42floors/class.rhtml +0 -39
- data/lib/rdoc/generator/template/42floors/file.rhtml +0 -35
- data/lib/rdoc/generator/template/42floors/index.rhtml +0 -13
- data/lib/rdoc/generator/template/42floors/resources/apple-touch-icon.png +0 -0
- data/lib/rdoc/generator/template/42floors/resources/css/github.css +0 -129
- data/lib/rdoc/generator/template/42floors/resources/css/main.css +0 -339
- data/lib/rdoc/generator/template/42floors/resources/css/panel.css +0 -389
- data/lib/rdoc/generator/template/42floors/resources/css/reset.css +0 -48
- data/lib/rdoc/generator/template/42floors/resources/favicon.ico +0 -0
- data/lib/rdoc/generator/template/42floors/resources/i/arrows.png +0 -0
- data/lib/rdoc/generator/template/42floors/resources/i/results_bg.png +0 -0
- data/lib/rdoc/generator/template/42floors/resources/i/tree_bg.png +0 -0
- data/lib/rdoc/generator/template/42floors/resources/js/highlight.pack.js +0 -1
- data/lib/rdoc/generator/template/42floors/resources/js/jquery-1.3.2.min.js +0 -19
- data/lib/rdoc/generator/template/42floors/resources/js/jquery-effect.js +0 -593
- data/lib/rdoc/generator/template/42floors/resources/js/main.js +0 -20
- data/lib/rdoc/generator/template/42floors/resources/js/searchdoc.js +0 -442
- data/lib/rdoc/generator/template/42floors/resources/panel/index.html +0 -73
- data/lib/rdoc/generator/template/42floors/se_index.rhtml +0 -8
- data/test/units/properties/test_boolean.rb +0 -4
- data/test/units/test_errors.rb +0 -32
- data/test/units/test_mls.rb +0 -294
- data/test/units/test_property.rb +0 -35
data/lib/mls/attributes/hash.rb
DELETED
data/lib/mls/errors.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
class MLS::Exception < Exception
|
2
|
-
end
|
3
|
-
|
4
|
-
class MLS::Exception::UnexpectedResponse < MLS::Exception
|
5
|
-
end
|
6
|
-
|
7
|
-
class MLS::Exception::BadRequest < MLS::Exception
|
8
|
-
end
|
9
|
-
|
10
|
-
class MLS::Exception::Unauthorized < MLS::Exception
|
11
|
-
end
|
12
|
-
|
13
|
-
class MLS::Exception::NotFound < MLS::Exception
|
14
|
-
end
|
15
|
-
|
16
|
-
class MLS::Exception::Gone < MLS::Exception
|
17
|
-
end
|
18
|
-
|
19
|
-
class MLS::Exception::MovedPermanently < MLS::Exception
|
20
|
-
end
|
21
|
-
|
22
|
-
class MLS::Exception::ApiVersionUnsupported < MLS::Exception
|
23
|
-
end
|
24
|
-
|
25
|
-
class MLS::Exception::RecordInvalid < MLS::Exception
|
26
|
-
end
|
27
|
-
|
28
|
-
class MLS::Exception::ServiceUnavailable < MLS::Exception
|
29
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
FactoryGirl.define do
|
2
|
-
factory :account, :class => MLS::Account do
|
3
|
-
name { Faker::Name.name }
|
4
|
-
email { Faker::Internet.email }
|
5
|
-
password { 'test' }
|
6
|
-
password_confirmation 'test'
|
7
|
-
end
|
8
|
-
|
9
|
-
factory :agent, :class => MLS::Account do
|
10
|
-
phone { Faker::PhoneNumber.phone_number }
|
11
|
-
company { Faker::Company.name }
|
12
|
-
license '12123123123'
|
13
|
-
name { Faker::Name.name }
|
14
|
-
email { Faker::Internet.email }
|
15
|
-
password 'test'
|
16
|
-
password_confirmation 'test'
|
17
|
-
type 'Agent'
|
18
|
-
end
|
19
|
-
|
20
|
-
factory :admin, :class => MLS::Account do
|
21
|
-
name { Faker::Name.name }
|
22
|
-
email { Faker::Internet.email }
|
23
|
-
type {'Admin'}
|
24
|
-
password { 'admin_test' }
|
25
|
-
password_confirmation 'admin_test'
|
26
|
-
end
|
27
|
-
|
28
|
-
factory :ghost_account, :class => MLS::Account do
|
29
|
-
name { Faker::Name.name }
|
30
|
-
email { Faker::Internet.email }
|
31
|
-
password_required { false }
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
@@ -1,16 +0,0 @@
|
|
1
|
-
FactoryGirl.define do
|
2
|
-
factory :address, :class => MLS::Address do
|
3
|
-
street_number { Kernel.rand(1000).to_s }
|
4
|
-
street { Faker::Address.street_name }
|
5
|
-
neighborhood { Faker::Name.name }
|
6
|
-
city { Faker::Address.city }
|
7
|
-
county { |p| p.city }
|
8
|
-
state { Faker::Address.state_abbr }
|
9
|
-
country 'US'
|
10
|
-
postal_code { Faker::Address.zip_code }
|
11
|
-
formatted_address { |p| "#{p.street_number} #{p.street}, #{p.city}, #{p.state}, #{p.postal_code}" }
|
12
|
-
latitude { Kernel.rand((-90.0)..(90.0)) }
|
13
|
-
longitude { Kernel.rand((-180.0)..(180.0)) }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
@@ -1,29 +0,0 @@
|
|
1
|
-
FactoryGirl.define do
|
2
|
-
factory :listing, :class => MLS::Listing do
|
3
|
-
before(:create) { |l|
|
4
|
-
MLS_GEM_CACHE['auth_cookie'] = MLS.auth_cookie
|
5
|
-
MLS.auth_cookie = l.account.auth_cookie
|
6
|
-
}
|
7
|
-
after(:create) { |l|
|
8
|
-
MLS.auth_cookie = MLS_GEM_CACHE['auth_cookie']
|
9
|
-
}
|
10
|
-
|
11
|
-
association :account
|
12
|
-
association :address, :strategy => :build
|
13
|
-
|
14
|
-
agents { [FactoryGirl.attributes_for(:agent)] }
|
15
|
-
|
16
|
-
use 'Office'
|
17
|
-
size { Kernel.rand(3000..900000) }
|
18
|
-
maximum_contiguous_size { Kernel.rand(3000..900000) }
|
19
|
-
minimum_divisible_size { Kernel.rand(3000..900000) }
|
20
|
-
type 'lease'
|
21
|
-
#lease_terms { ::MLS::Listing::LEASE_TERMS.sample }
|
22
|
-
space_type 'unit'
|
23
|
-
rate { rand(15..300) }
|
24
|
-
available_on { Time.now + (20 + rand(0..360).to_i).days }
|
25
|
-
sublease_expiration { |l| l.sublease? ? (l.available_on + (30 + Kernel.rand(10..360)).days) : nil }
|
26
|
-
name { |l| l.type == 'coworking_space' ? Faker::Name.name : nil }
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
data/lib/mls/factories_helper.rb
DELETED
data/lib/mls/model.rb
DELETED
@@ -1,125 +0,0 @@
|
|
1
|
-
module MLS::Model
|
2
|
-
|
3
|
-
def self.extended(model) #:nodoc:
|
4
|
-
model.instance_variable_set(:@attributes, {})
|
5
|
-
model.instance_variable_set(:@associations, {})
|
6
|
-
end
|
7
|
-
|
8
|
-
# Creates an object and saves it to the MLS. The resulting object is returned
|
9
|
-
# whether or no the object was saved successfully to the MLS or not.
|
10
|
-
#
|
11
|
-
# ==== Examples
|
12
|
-
# #!ruby
|
13
|
-
# # Create a single new object
|
14
|
-
# User.create(:first_name => 'Jamie')
|
15
|
-
#
|
16
|
-
# # Create a single object and pass it into a block to set other attributes.
|
17
|
-
# User.create(:first_name => 'Jamie') do |u|
|
18
|
-
# u.is_admin = false
|
19
|
-
# end
|
20
|
-
def create(attributes={}, &block) # TODO: testme
|
21
|
-
model = self.new(attributes)
|
22
|
-
yield(model) if block_given?
|
23
|
-
model.save
|
24
|
-
model
|
25
|
-
end
|
26
|
-
|
27
|
-
# Attributes ===================================================================================================
|
28
|
-
|
29
|
-
def attribute(name, type, options = {})
|
30
|
-
klass = MLS::Attribute.determine_class(type)
|
31
|
-
raise NotImplementedError, "#{type} is not supported" unless klass
|
32
|
-
|
33
|
-
attribute = klass.new(name, options)
|
34
|
-
@attributes[attribute.name] = attribute
|
35
|
-
@attributes_excluded_from_comparison = []
|
36
|
-
|
37
|
-
create_reader_for(attribute)
|
38
|
-
create_writer_for(attribute)
|
39
|
-
end
|
40
|
-
|
41
|
-
def exclude_from_comparison(*attributes)
|
42
|
-
@attributes_excluded_from_comparison |= attributes
|
43
|
-
end
|
44
|
-
|
45
|
-
def attributes_excluded_from_comparison
|
46
|
-
@attributes_excluded_from_comparison
|
47
|
-
end
|
48
|
-
|
49
|
-
def attributes
|
50
|
-
@attributes
|
51
|
-
end
|
52
|
-
|
53
|
-
def attribute_module
|
54
|
-
@attribute_module ||= begin
|
55
|
-
mod = Module.new
|
56
|
-
class_eval do
|
57
|
-
include mod
|
58
|
-
end
|
59
|
-
mod
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def create_reader_for(attribute)
|
64
|
-
reader_name = attribute.name.to_s
|
65
|
-
boolean_reader_name = "#{reader_name}?"
|
66
|
-
reader_visibility = attribute.reader_visibility
|
67
|
-
instance_variable_name = attribute.instance_variable_name
|
68
|
-
|
69
|
-
attribute_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
70
|
-
#{reader_visibility}
|
71
|
-
def #{reader_name}
|
72
|
-
return #{instance_variable_name} if defined?(#{instance_variable_name})
|
73
|
-
attribute = attributes[:#{reader_name}]
|
74
|
-
#{instance_variable_name} = attribute ? attribute.default : nil
|
75
|
-
end
|
76
|
-
RUBY
|
77
|
-
|
78
|
-
if attribute.kind_of?(MLS::Attribute::Boolean)
|
79
|
-
attribute_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
80
|
-
#{reader_visibility}
|
81
|
-
def #{boolean_reader_name}
|
82
|
-
#{reader_name}
|
83
|
-
end
|
84
|
-
RUBY
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def create_writer_for(attribute)
|
89
|
-
name = attribute.name
|
90
|
-
writer_name = "#{name}="
|
91
|
-
writer_visibility = attribute.writer_visibility
|
92
|
-
instance_variable_name = attribute.instance_variable_name
|
93
|
-
|
94
|
-
attribute_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
95
|
-
#{writer_visibility}
|
96
|
-
def #{writer_name}(value)
|
97
|
-
attribute = self.class.attributes[:#{name}]
|
98
|
-
#{instance_variable_name} = attribute.load(value)
|
99
|
-
end
|
100
|
-
RUBY
|
101
|
-
end
|
102
|
-
|
103
|
-
#== for rails form stuff
|
104
|
-
def model_name
|
105
|
-
self
|
106
|
-
end
|
107
|
-
|
108
|
-
def param_key
|
109
|
-
root_element.to_s
|
110
|
-
end
|
111
|
-
|
112
|
-
# used for parser
|
113
|
-
def root_element_string
|
114
|
-
ActiveSupport::Inflector.demodulize(self).underscore
|
115
|
-
end
|
116
|
-
|
117
|
-
def root_element
|
118
|
-
@root_element ||= root_element_string.to_sym
|
119
|
-
end
|
120
|
-
|
121
|
-
def collection_root_element
|
122
|
-
@collection_root_element ||= root_element_string.pluralize.to_sym
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
data/lib/mls/models/account.rb
DELETED
@@ -1,174 +0,0 @@
|
|
1
|
-
class MLS::Account < MLS::Resource
|
2
|
-
|
3
|
-
attribute :id, Fixnum, :serialize => :if_present
|
4
|
-
attribute :type, String, :default => 'Account'
|
5
|
-
attribute :name, String, :serialize => :if_present
|
6
|
-
attribute :title, String, :serialize => :if_present
|
7
|
-
attribute :email, String, :serialize => :if_present
|
8
|
-
attribute :password, String, :serialize => :if_present
|
9
|
-
attribute :password_confirmation, String, :serialize => :if_present
|
10
|
-
attribute :perishable_token, String, :serialize => false
|
11
|
-
attribute :perishable_token_set_at, String, :serialize => false
|
12
|
-
attribute :ghost, Boolean, :serialize => false, :default => false
|
13
|
-
|
14
|
-
attribute :phone, String, :serialize => :if_present
|
15
|
-
attribute :company, String, :serialize => :if_present
|
16
|
-
attribute :license, String, :serialize => :if_present
|
17
|
-
attribute :linkedin, String, :serialize => :if_present
|
18
|
-
attribute :twitter, String, :serialize => :if_present
|
19
|
-
attribute :facebook, String, :serialize => :if_present
|
20
|
-
attribute :web, String, :serialize => :if_present
|
21
|
-
attribute :direct_phone, String, :serialize => :if_present
|
22
|
-
attribute :direct_email, String, :serialize => :if_present
|
23
|
-
|
24
|
-
attribute :city, String, :serialize => :if_present
|
25
|
-
attribute :state, String, :serialize => :if_present
|
26
|
-
attribute :country, String, :serialize => :if_present
|
27
|
-
|
28
|
-
attribute :created_at, DateTime, :serialize => :false
|
29
|
-
attribute :updated_at, DateTime, :serialize => :false
|
30
|
-
|
31
|
-
attribute :email_token, String, :serialize => false
|
32
|
-
attribute :start_hours_of_operation, Fixnum, :serialize => :if_present
|
33
|
-
attribute :end_hours_of_operation, Fixnum, :serialize => :if_present
|
34
|
-
attribute :days_of_operation, String, :serialize => :if_present
|
35
|
-
attribute :timezone, String, :serialize => :if_present
|
36
|
-
attribute :lead_status, String, :serialize => :if_present
|
37
|
-
attribute :buyer_id, Fixnum, :serialize => :if_present
|
38
|
-
|
39
|
-
exclude_from_comparison :password, :password_confirmation
|
40
|
-
|
41
|
-
attr_accessor :password_required, :brokerage
|
42
|
-
|
43
|
-
attr_writer :favorites
|
44
|
-
|
45
|
-
def update
|
46
|
-
raise "cannot update account without id" unless id
|
47
|
-
MLS.put("/accounts/#{id}", { :account => to_hash}, 400) do |response, code|
|
48
|
-
MLS::Account::Parser.update(self, response.body)
|
49
|
-
code == 200
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# Save the Account to the MLS. @errors will be set on the account if there
|
54
|
-
# are any errors. @persisted will also be set to +true+ if the Account was
|
55
|
-
# succesfully created
|
56
|
-
def create
|
57
|
-
MLS.post('/accounts', {:account => to_hash}, 400) do |response, code|
|
58
|
-
raise MLS::Exception::UnexpectedResponse if ![201, 400].include?(code)
|
59
|
-
MLS::Account::Parser.update(self, response.body)
|
60
|
-
@persisted = true
|
61
|
-
code == 201
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def display_name
|
66
|
-
name || email
|
67
|
-
end
|
68
|
-
|
69
|
-
def agent?
|
70
|
-
type == 'Agent'
|
71
|
-
end
|
72
|
-
|
73
|
-
def favorites
|
74
|
-
return @favorites if @favorites
|
75
|
-
response = MLS.get('/account/favorites')
|
76
|
-
@favorites = MLS::Listing::Parser.parse_collection(response.body, {:collection_root_element => :favorites})
|
77
|
-
end
|
78
|
-
|
79
|
-
def agent_profile
|
80
|
-
@agent_profile ||= MLS.agent_profile id
|
81
|
-
end
|
82
|
-
|
83
|
-
def favorited?(listing)
|
84
|
-
favorites.include?(listing)
|
85
|
-
end
|
86
|
-
|
87
|
-
def favorite(listing) # TODO: test me, i don't work on failures
|
88
|
-
params_hash = {:id => listing.is_a?(MLS::Listing) ? listing.id : listing }
|
89
|
-
MLS.post('/account/favorites', params_hash) do |response, code|
|
90
|
-
@favorites = nil
|
91
|
-
true
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def unfavorite(listing_id) # TODO: test me, i don't work on failures
|
96
|
-
listing_id = listing_id.is_a?(MLS::Listing) ? listing_id.id : listing_id
|
97
|
-
MLS.delete("/account/favorites/#{listing_id}") do |response, code|
|
98
|
-
@favorites = nil
|
99
|
-
true
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def to_hash
|
104
|
-
hash = super
|
105
|
-
hash[:password_required] = password_required unless password_required.nil?
|
106
|
-
hash
|
107
|
-
end
|
108
|
-
|
109
|
-
class << self
|
110
|
-
|
111
|
-
def current
|
112
|
-
response = MLS.get('/account')
|
113
|
-
MLS::Account::Parser.parse(response.body)
|
114
|
-
end
|
115
|
-
|
116
|
-
# Authenticate and Account via <tt>email</tt> and <tt>password</tt>. Returns
|
117
|
-
# the <tt>Account</tt> object if successfully authenticated. Returns <tt>nil</tt>
|
118
|
-
# if the account could not be found, password was incorrect, or the account
|
119
|
-
# was revoked
|
120
|
-
#
|
121
|
-
# ==== Examples
|
122
|
-
# #!ruby
|
123
|
-
# Account.authenticate(:email => 'jon@does.net', :password => 'opensesame') # => #<Account>
|
124
|
-
#
|
125
|
-
# Account.authenticate('jon@does.net', 'opensesame') # => #<Account>
|
126
|
-
#
|
127
|
-
# Account.authenticate('jon@does.net', 'wrong') # => nil
|
128
|
-
def authenticate(attrs_or_email, password=nil)
|
129
|
-
email = attrs_or_email.is_a?(Hash) ? attrs_or_email[:email] : attrs_or_email
|
130
|
-
password = attrs_or_email.is_a?(Hash) ? attrs_or_email[:password] : password
|
131
|
-
response = MLS.post('/login', {:email => email, :password => password})
|
132
|
-
account = MLS::Account::Parser.parse(response.body)
|
133
|
-
account
|
134
|
-
rescue MLS::Exception::Unauthorized => response
|
135
|
-
nil
|
136
|
-
end
|
137
|
-
|
138
|
-
# URL is currently required to not have any query params in it
|
139
|
-
def reset_password!(email, url)
|
140
|
-
MLS.post('/account/password', {:email => email, :url => url}, 400, 404) do |response, code|
|
141
|
-
code == 204
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def update_password!(token, password, password_confirmation)
|
146
|
-
MLS.put('/account/password', {:token => token, :password => password, :password_confirmation => password_confirmation}, 400) do |response, code|
|
147
|
-
MLS::Account::Parser.parse(response.body)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def find(id, includes=[])
|
152
|
-
response = MLS.get("/accounts/#{id}", :include => includes)
|
153
|
-
MLS::Account::Parser.parse(response.body)
|
154
|
-
end
|
155
|
-
|
156
|
-
def where(terms)
|
157
|
-
response = MLS.get('/accounts', :where => terms)
|
158
|
-
MLS::Account::Parser.parse_collection(response.body)
|
159
|
-
end
|
160
|
-
|
161
|
-
end
|
162
|
-
|
163
|
-
end
|
164
|
-
|
165
|
-
class MLS::Account::Parser < MLS::Parser
|
166
|
-
|
167
|
-
def favorites=(favorites)
|
168
|
-
@object.favorites = favorites.map {|a| MLS::Listing::Parser.build(a) }
|
169
|
-
end
|
170
|
-
|
171
|
-
def brokerage=(brokerage)
|
172
|
-
@object.brokerage = MLS::Brokerage::Parser.build(brokerage)
|
173
|
-
end
|
174
|
-
end
|