mls 0.14.0 → 1.0.0

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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/Rakefile +6 -6
  4. data/lib/mls.rb +73 -427
  5. data/lib/mls/account.rb +15 -0
  6. data/lib/mls/address.rb +4 -0
  7. data/lib/mls/agency.rb +6 -0
  8. data/lib/mls/brokerage.rb +7 -0
  9. data/lib/mls/coworking_space.rb +5 -0
  10. data/lib/mls/floorplan.rb +11 -0
  11. data/lib/mls/flyer.rb +11 -0
  12. data/lib/mls/lease.rb +2 -0
  13. data/lib/mls/listing.rb +135 -0
  14. data/lib/mls/locality.rb +6 -0
  15. data/lib/mls/photo.rb +18 -0
  16. data/lib/mls/property.rb +24 -0
  17. data/lib/mls/region.rb +13 -0
  18. data/lib/mls/sale.rb +2 -0
  19. data/lib/mls/space.rb +3 -0
  20. data/lib/mls/sublease.rb +2 -0
  21. data/lib/mls/use.rb +25 -0
  22. data/mls.gemspec +11 -15
  23. data/test/mls/attribute_test.rb +55 -0
  24. data/test/mls/resource_test.rb +31 -0
  25. data/test/mls_test.rb +27 -0
  26. data/test/test_helper.rb +26 -27
  27. metadata +43 -75
  28. data/lib/mls/attribute.rb +0 -44
  29. data/lib/mls/attributes/array.rb +0 -11
  30. data/lib/mls/attributes/boolean.rb +0 -9
  31. data/lib/mls/attributes/datetime.rb +0 -25
  32. data/lib/mls/attributes/decimal.rb +0 -21
  33. data/lib/mls/attributes/fixnum.rb +0 -16
  34. data/lib/mls/attributes/hash.rb +0 -15
  35. data/lib/mls/attributes/string.rb +0 -15
  36. data/lib/mls/errors.rb +0 -29
  37. data/lib/mls/factories/account.rb +0 -34
  38. data/lib/mls/factories/address.rb +0 -16
  39. data/lib/mls/factories/listing.rb +0 -29
  40. data/lib/mls/factories_helper.rb +0 -7
  41. data/lib/mls/model.rb +0 -125
  42. data/lib/mls/models/account.rb +0 -174
  43. data/lib/mls/models/address.rb +0 -58
  44. data/lib/mls/models/brokerage.rb +0 -31
  45. data/lib/mls/models/floorplan.rb +0 -45
  46. data/lib/mls/models/flyer.rb +0 -45
  47. data/lib/mls/models/listing.rb +0 -394
  48. data/lib/mls/models/pdf.rb +0 -15
  49. data/lib/mls/models/photo.rb +0 -40
  50. data/lib/mls/models/property.rb +0 -114
  51. data/lib/mls/models/region.rb +0 -56
  52. data/lib/mls/models/tour.rb +0 -54
  53. data/lib/mls/models/video.rb +0 -18
  54. data/lib/mls/parser.rb +0 -74
  55. data/lib/mls/resource.rb +0 -99
  56. data/lib/rdoc/generator/template/42floors/_context.rhtml +0 -209
  57. data/lib/rdoc/generator/template/42floors/_head.rhtml +0 -7
  58. data/lib/rdoc/generator/template/42floors/class.rhtml +0 -39
  59. data/lib/rdoc/generator/template/42floors/file.rhtml +0 -35
  60. data/lib/rdoc/generator/template/42floors/index.rhtml +0 -13
  61. data/lib/rdoc/generator/template/42floors/resources/apple-touch-icon.png +0 -0
  62. data/lib/rdoc/generator/template/42floors/resources/css/github.css +0 -129
  63. data/lib/rdoc/generator/template/42floors/resources/css/main.css +0 -339
  64. data/lib/rdoc/generator/template/42floors/resources/css/panel.css +0 -389
  65. data/lib/rdoc/generator/template/42floors/resources/css/reset.css +0 -48
  66. data/lib/rdoc/generator/template/42floors/resources/favicon.ico +0 -0
  67. data/lib/rdoc/generator/template/42floors/resources/i/arrows.png +0 -0
  68. data/lib/rdoc/generator/template/42floors/resources/i/results_bg.png +0 -0
  69. data/lib/rdoc/generator/template/42floors/resources/i/tree_bg.png +0 -0
  70. data/lib/rdoc/generator/template/42floors/resources/js/highlight.pack.js +0 -1
  71. data/lib/rdoc/generator/template/42floors/resources/js/jquery-1.3.2.min.js +0 -19
  72. data/lib/rdoc/generator/template/42floors/resources/js/jquery-effect.js +0 -593
  73. data/lib/rdoc/generator/template/42floors/resources/js/main.js +0 -20
  74. data/lib/rdoc/generator/template/42floors/resources/js/searchdoc.js +0 -442
  75. data/lib/rdoc/generator/template/42floors/resources/panel/index.html +0 -73
  76. data/lib/rdoc/generator/template/42floors/se_index.rhtml +0 -8
  77. data/test/units/properties/test_boolean.rb +0 -4
  78. data/test/units/test_errors.rb +0 -32
  79. data/test/units/test_mls.rb +0 -294
  80. data/test/units/test_property.rb +0 -35
@@ -1,16 +0,0 @@
1
- class MLS::Attribute::Fixnum < ::MLS::Attribute
2
-
3
- def load(value) # from_json
4
- if value.nil?
5
- nil
6
- elsif value.is_a?(::Fixnum)
7
- value
8
- else
9
- value.to_i
10
- end
11
-
12
- end
13
-
14
- alias :dump :load #only for primatives
15
-
16
- end
@@ -1,15 +0,0 @@
1
- class MLS::Attribute::Hash < MLS::Attribute
2
-
3
- def load(value) # from_json
4
- if value.is_a?(Hash)
5
- value.with_indifferent_access
6
- else
7
- value
8
- end
9
- end
10
-
11
- def dump(value)
12
- value
13
- end
14
-
15
- end
@@ -1,15 +0,0 @@
1
- class MLS::Attribute::String < MLS::Attribute
2
-
3
- def load(value) # from_json
4
- if value.nil?
5
- nil
6
- elsif value.is_a?(::String)
7
- value
8
- else
9
- value.to_s
10
- end
11
- end
12
-
13
- alias :dump :load #only for primatives
14
-
15
- end
@@ -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
-
@@ -1,7 +0,0 @@
1
- require 'factory_girl'
2
-
3
- factories_dir = File.join(File.dirname(__FILE__), 'factories')
4
- FactoryGirl.definition_file_paths = [factories_dir]
5
- FactoryGirl.find_definitions
6
-
7
- MLS_GEM_CACHE={}
@@ -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
@@ -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