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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mls.rb +46 -46
  3. data/lib/mls/{property.rb → attribute.rb} +2 -2
  4. data/lib/mls/{properties → attributes}/array.rb +1 -1
  5. data/lib/mls/{properties → attributes}/boolean.rb +1 -1
  6. data/lib/mls/{properties → attributes}/datetime.rb +1 -1
  7. data/lib/mls/{properties → attributes}/decimal.rb +1 -1
  8. data/lib/mls/{properties → attributes}/fixnum.rb +1 -1
  9. data/lib/mls/{properties → attributes}/hash.rb +1 -1
  10. data/lib/mls/{properties → attributes}/string.rb +1 -1
  11. data/lib/mls/factories/listing.rb +3 -3
  12. data/lib/mls/model.rb +33 -33
  13. data/lib/mls/models/account.rb +55 -46
  14. data/lib/mls/models/address.rb +18 -117
  15. data/lib/mls/models/brokerage.rb +6 -6
  16. data/lib/mls/models/floorplan.rb +5 -5
  17. data/lib/mls/models/flyer.rb +5 -5
  18. data/lib/mls/models/listing.rb +80 -76
  19. data/lib/mls/models/pdf.rb +4 -4
  20. data/lib/mls/models/photo.rb +10 -10
  21. data/lib/mls/models/property.rb +113 -0
  22. data/lib/mls/models/region.rb +14 -14
  23. data/lib/mls/models/tour.rb +10 -10
  24. data/lib/mls/models/video.rb +7 -7
  25. data/lib/mls/parser.rb +1 -1
  26. data/lib/mls/resource.rb +15 -15
  27. data/lib/rdoc/generator/template/42floors/resources/css/github.css +1 -1
  28. data/lib/rdoc/generator/template/42floors/resources/js/highlight.pack.js +1 -1
  29. data/lib/rdoc/generator/template/42floors/resources/js/jquery-1.3.2.min.js +1 -1
  30. data/lib/rdoc/generator/template/42floors/resources/js/jquery-effect.js +6 -6
  31. data/mls.gemspec +1 -1
  32. data/test/test_helper.rb +1 -1
  33. data/test/units/models/test_address.rb +4 -4
  34. data/test/units/models/test_contact.rb +1 -1
  35. data/test/units/models/test_listing.rb +4 -4
  36. data/test/units/test_mls.rb +60 -60
  37. data/test/units/test_model.rb +3 -3
  38. data/test/units/test_property.rb +18 -18
  39. data/test/units/test_resource.rb +1 -1
  40. metadata +12 -11
@@ -1,43 +1,45 @@
1
1
  class MLS::Account < MLS::Resource
2
-
3
- property :id, Fixnum, :serialize => :if_present
4
- property :type, String, :default => 'Account'
5
- property :name, String, :serialize => :if_present
6
- property :title, String, :serialize => :if_present
7
- property :email, String, :serialize => :if_present
8
- property :password, String, :serialize => :if_present
9
- property :password_confirmation, String, :serialize => :if_present
10
- property :perishable_token, String, :serialize => false
11
- property :perishable_token_set_at, String, :serialize => false
12
- property :ghost, Boolean, :serialize => false, :default => false
13
-
14
- property :phone, String, :serialize => :if_present
15
- property :company, String, :serialize => :if_present
16
- property :license, String, :serialize => :if_present
17
- property :linkedin, String, :serialize => :if_present
18
- property :twitter, String, :serialize => :if_present
19
- property :facebook, String, :serialize => :if_present
20
- property :web, String, :serialize => :if_present
21
-
22
- property :city, String, :serialize => :if_present
23
- property :state, String, :serialize => :if_present
24
- property :country, String, :serialize => :if_present
25
-
26
- property :created_at, DateTime, :serialize => :false
27
- property :updated_at, DateTime, :serialize => :false
28
-
29
- property :email_token, String, :serialize => false
30
- property :auth_key, String, :serialize => false
31
- property :start_hours_of_operation, Fixnum, :serialize => :if_present
32
- property :end_hours_of_operation, Fixnum, :serialize => :if_present
33
- property :days_of_operation, String, :serialize => :if_present
34
- property :timezone, String, :serialize => :if_present
35
- property :lead_status, String, :serialize => :if_present
36
- property :buyer_id, Fixnum, :serialize => :if_present
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 :auth_cookie, String, :serialize => false
33
+ attribute :start_hours_of_operation, Fixnum, :serialize => :if_present
34
+ attribute :end_hours_of_operation, Fixnum, :serialize => :if_present
35
+ attribute :days_of_operation, String, :serialize => :if_present
36
+ attribute :timezone, String, :serialize => :if_present
37
+ attribute :lead_status, String, :serialize => :if_present
38
+ attribute :buyer_id, Fixnum, :serialize => :if_present
37
39
 
38
40
  exclude_from_comparison :password, :password_confirmation
39
41
 
40
- attr_accessor :password_required
42
+ attr_accessor :password_required, :brokerage
41
43
 
42
44
  attr_writer :favorites
43
45
 
@@ -47,7 +49,7 @@ class MLS::Account < MLS::Resource
47
49
  code == 200
48
50
  end
49
51
  end
50
-
52
+
51
53
  # Save the Account to the MLS. @errors will be set on the account if there
52
54
  # are any errors. @persisted will also be set to +true+ if the Account was
53
55
  # succesfully created
@@ -81,7 +83,7 @@ class MLS::Account < MLS::Resource
81
83
  def favorited?(listing)
82
84
  favorites.include?(listing)
83
85
  end
84
-
86
+
85
87
  def favorite(listing) # TODO: test me, i don't work on failures
86
88
  params_hash = {:id => listing.is_a?(MLS::Listing) ? listing.id : listing }
87
89
  MLS.post('/account/favorites', params_hash) do |response, code|
@@ -103,14 +105,14 @@ class MLS::Account < MLS::Resource
103
105
  hash[:password_required] = password_required unless password_required.nil?
104
106
  hash
105
107
  end
106
-
108
+
107
109
  class << self
108
110
 
109
111
  def current
110
112
  response = MLS.get('/account')
111
113
  MLS::Account::Parser.parse(response.body)
112
114
  end
113
-
115
+
114
116
  # Authenticate and Account via <tt>email</tt> and <tt>password</tt>. Returns
115
117
  # the <tt>Account</tt> object if successfully authenticated. Returns <tt>nil</tt>
116
118
  # if the account could not be found, password was incorrect, or the account
@@ -119,16 +121,20 @@ class MLS::Account < MLS::Resource
119
121
  # ==== Examples
120
122
  # #!ruby
121
123
  # Account.authenticate(:email => 'jon@does.net', :password => 'opensesame') # => #<Account>
122
- #
124
+ #
123
125
  # Account.authenticate('jon@does.net', 'opensesame') # => #<Account>
124
126
  #
125
127
  # Account.authenticate('jon@does.net', 'wrong') # => nil
126
128
  def authenticate(attrs_or_email, password=nil)
127
129
  email = attrs_or_email.is_a?(Hash) ? attrs_or_email[:email] : attrs_or_email
128
130
  password = attrs_or_email.is_a?(Hash) ? attrs_or_email[:password] : password
129
-
130
- response = MLS.get('/account', {:email => email, :password => password})
131
- MLS::Account::Parser.parse(response.body)
131
+
132
+ response = MLS.post('/login', {:email => email, :password => password})
133
+ MLS.auth_cookie = response['set-cookie']
134
+
135
+ account = MLS::Account::Parser.parse(response.body)
136
+ account.auth_cookie = MLS.auth_cookie
137
+ account
132
138
  rescue MLS::Exception::Unauthorized => response
133
139
  nil
134
140
  end
@@ -151,12 +157,12 @@ class MLS::Account < MLS::Resource
151
157
  end
152
158
 
153
159
  def find(id)
154
- response = MLS.get("/account/find", :id => id)
160
+ response = MLS.get("/account/find", :id => id)
155
161
  MLS::Account::Parser.parse(response.body)
156
162
  end
157
163
 
158
164
  end
159
-
165
+
160
166
  end
161
167
 
162
168
  class MLS::Account::Parser < MLS::Parser
@@ -165,4 +171,7 @@ class MLS::Account::Parser < MLS::Parser
165
171
  @object.favorites = favorites.map {|a| MLS::Listing::Parser.build(a) }
166
172
  end
167
173
 
174
+ def brokerage=(brokerage)
175
+ @object.brokerage = MLS::Brokerage::Parser.build(brokerage)
176
+ end
168
177
  end
@@ -1,65 +1,21 @@
1
1
  class MLS::Address < MLS::Resource
2
2
 
3
- property :id, Fixnum, :serialize => :false
4
- property :name, String, :serialize => :false
5
- property :slug, String, :serialize => :false
3
+ attribute :id, Fixnum, :serialize => :false
4
+ attribute :property_id, Fixnum, :serialize => :false
5
+ attribute :slug, String, :serialize => :false
6
6
 
7
- property :latitude, Decimal
8
- property :longitude, Decimal
7
+ attribute :formatted_address, String
8
+ attribute :street_number, String
9
+ attribute :street, String
10
+ attribute :neighborhood, String
11
+ attribute :city, String
12
+ attribute :county, String
13
+ attribute :state, String
14
+ attribute :country, String
15
+ attribute :postal_code, String
9
16
 
10
- property :formatted_address, String
11
- property :street_number, String
12
- property :street, String
13
- property :neighborhood, String
14
- property :city, String
15
- property :county, String
16
- property :state, String
17
- property :country, String
18
- property :postal_code, String
19
- property :min_rate_per_sqft_per_year, Decimal, :serialize => :false
20
- property :max_rate_per_sqft_per_year, Decimal, :serialize => :false
21
- property :max_size, Fixnum, :serialize => :false
22
- property :min_size, Fixnum, :serialize => :false
23
- property :description, String
24
- property :year_built, Fixnum
25
- property :size, Fixnum
26
- property :floors, Fixnum
27
-
28
- property :amenities, Hash
29
-
30
- property :leed_certification, String
17
+ attr_accessor :property
31
18
 
32
- # Counter caches
33
- property :listings_count, Fixnum, :serialize => :false
34
- property :leased_listings_count, Fixnum, :serialize => :false
35
- property :hidden_listings_count, Fixnum, :serialize => :false
36
- property :import_listings_count, Fixnum, :serialize => :false
37
- property :active_listings_count, Fixnum, :serialize => :false
38
-
39
- property :avatar_digest, String, :serialize => false
40
-
41
- property :listings_latest_created_at, DateTime, :serialize => :false
42
-
43
- attr_accessor :listings, :listing_types, :photos, :videos
44
-
45
- # should include an optional use address or no_image image
46
- def avatar(size='100x200#', protocol='http')
47
- params = {
48
- :size => size,
49
- :format => 'png',
50
- :sensor => false,
51
- :location => [formatted_address],
52
- :fov => 120
53
- }
54
-
55
- if avatar_digest
56
- "#{protocol}://#{MLS.image_host}/#{avatar_digest}.jpg?s=#{URI.escape(size)}"
57
- else
58
- params[:size] = params[:size].match(/\d+x\d+/)[0]
59
- "#{protocol}://maps.googleapis.com/maps/api/streetview?" + params.map{|k,v| k.to_s + '=' + URI.escape(v.to_s) }.join('&')
60
- end
61
- end
62
-
63
19
  def save
64
20
  MLS.put("/addresses/#{id}", {:address => to_hash}, 400) do |response, code|
65
21
  if code == 200 || code == 400
@@ -71,45 +27,11 @@ class MLS::Address < MLS::Resource
71
27
  end
72
28
  end
73
29
 
74
- def to_hash
75
- hash = super
76
- hash[:photo_ids] = photos.map(&:id) if photos
77
- hash[:videos_attributes] = videos.map(&:to_hash) unless videos.blank?
78
- hash
79
- end
80
-
81
30
  def to_param
82
- [state, city, "#{street_number} #{street}"].map(&:parameterize).join('/')
83
- end
84
-
85
- def url
86
- if defined? Rails
87
- case Rails.env
88
- when "production"
89
- host = "42floors.com"
90
- when "staging"
91
- host = "staging.42floors.com"
92
- when "development","test"
93
- host = "spire.dev"
94
- end
95
- else
96
- host = "42floors.com"
97
- end
98
- "http://#{host}/#{slug}"
99
- end
100
-
101
- def find_listings(space_available, floor, unit)
102
- response = MLS.get("/addresses/#{id}/find_listings",
103
- :floor => floor, :unit => unit, :space_available => space_available)
104
- MLS::Listing::Parser.parse_collection(response.body)
31
+ slug
105
32
  end
106
33
 
107
34
  class << self
108
-
109
- def query(q)
110
- response = MLS.get('/addresses/query', :query => q)
111
- MLS::Address::Parser.parse_collection(response.body)
112
- end
113
35
 
114
36
  def find(id)
115
37
  response = MLS.get("/addresses/#{id}")
@@ -122,36 +44,15 @@ class MLS::Address < MLS::Resource
122
44
  MLS::Address::Parser.parse_collection(response.body)
123
45
  end
124
46
 
125
- def amenities
126
- @amenities ||= Yajl::Parser.new(:symbolize_keys => true).parse(MLS.get('/addresses/amenities').body)
127
- end
128
-
129
47
  end
130
48
 
131
49
  end
132
50
 
133
51
 
134
52
  class MLS::Address::Parser < MLS::Parser
135
-
136
- def listings=(listings)
137
- @object.listings = listings.map { |data|
138
- listing = MLS::Listing::Parser.build(data)
139
- listing.address = @object
140
- listing
141
- }
142
- end
143
-
144
- def listing_types=(listing_types)
145
- @object.listing_types = listing_types
146
- end
147
-
148
- def photos=(photos)
149
- @object.photos = photos.map {|p| MLS::Photo::Parser.build(p)}
150
- end
151
-
152
- def videos=(videos)
153
- @object.videos = videos.map do |video|
154
- MLS::Video::Parser.build(video)
155
- end
53
+
54
+ def property=(property)
55
+ @object.property = MLS::Property::Parser.build(property)
156
56
  end
57
+
157
58
  end
@@ -1,11 +1,11 @@
1
1
  class MLS::Brokerage < MLS::Resource
2
2
 
3
- property :id, Fixnum, :serialize => :if_present
4
- property :name, String, :serialize => :if_present
5
- property :admin_id, Fixnum, :serialize => :if_present
6
- property :slug, String, :serialize => false
7
- property :palette, Hash, :serialize => :if_present
8
- property :avatar_digest, String, :serialize => false
3
+ attribute :id, Fixnum, :serialize => :if_present
4
+ attribute :name, String, :serialize => :if_present
5
+ attribute :admin_id, Fixnum, :serialize => :if_present
6
+ attribute :slug, String, :serialize => false
7
+ attribute :palette, Hash, :serialize => :if_present
8
+ attribute :avatar_digest, String, :serialize => false
9
9
 
10
10
  class << self
11
11
 
@@ -2,11 +2,11 @@ require 'restclient'
2
2
 
3
3
  class MLS::Floorplan < MLS::Resource
4
4
 
5
- property :id, Fixnum
6
- property :digest, String
7
- property :avatar_digest, String
8
- property :file_name, String
9
- property :file_size, Fixnum
5
+ attribute :id, Fixnum
6
+ attribute :digest, String
7
+ attribute :avatar_digest, String
8
+ attribute :file_name, String
9
+ attribute :file_size, Fixnum
10
10
 
11
11
  def url(protocol='http')
12
12
  "#{protocol}://#{MLS.asset_host}/floorplans/#{digest}/compressed/#{file_name}"
@@ -2,11 +2,11 @@ require 'restclient'
2
2
 
3
3
  class MLS::Flyer < MLS::Resource
4
4
 
5
- property :id, Fixnum
6
- property :digest, String
7
- property :avatar_digest, String
8
- property :file_name, String
9
- property :file_size, Fixnum
5
+ attribute :id, Fixnum
6
+ attribute :digest, String
7
+ attribute :avatar_digest, String
8
+ attribute :file_name, String
9
+ attribute :file_size, Fixnum
10
10
 
11
11
  def url(protocol='http')
12
12
  "#{protocol}://#{MLS.asset_host}/flyers/#{digest}/compressed/#{file_name}"
@@ -10,85 +10,85 @@ class MLS::Listing < MLS::Resource
10
10
  SOURCE_TYPES = %w(website flyer)
11
11
  CHANNELS = %w(excavator mls staircase broker_dashboard)
12
12
 
13
- property :id, Fixnum, :serialize => :false
14
- property :address_id, Fixnum, :serialize => :false
15
- property :slug, String, :serialize => :false
16
- property :use, String, :serialize => :if_present
17
- property :account_id, Fixnum
18
- property :private, Boolean, :default => false, :serialize => false
19
- property :source, String
20
- property :source_url, String
21
- property :source_type, String, :serialize => :if_present
22
- property :channel, String, :serialize => :if_present
23
- property :photo_ids, Array, :serialize => :if_present
24
-
25
- property :name, String
26
- property :type, String, :default => 'lease'
27
- property :workflow_state, String, :default => 'visible'
28
- property :lease_state, String, :default => 'listed'
29
- property :space_type, String, :default => 'unit'
30
- property :unit, String
31
- property :floor, Fixnum
32
- property :description, String
33
-
34
- property :size, Fixnum
35
- property :maximum_contiguous_size, Fixnum
36
- property :minimum_divisible_size, Fixnum
37
-
38
- property :amenities, Hash
39
- property :lease_terms, String
40
- property :rate, Decimal
41
- property :rate_units, String, :default => '/sqft/mo'
42
- property :low_rate, Decimal, :serialize => :false
43
- property :high_rate, Decimal, :serialize => :false
44
- property :sublease_expiration, DateTime
45
-
46
- property :forecast_rate_per_year, Decimal, :serialize => :false
47
- property :forecast_rate_per_month, Decimal, :serialize => :false
48
- property :forecast_rate_per_sqft_per_month, Decimal, :serialize => :false
49
- property :forecast_rate_per_sqft_per_year, Decimal, :serialize => :false
50
-
51
- property :available_on, DateTime
52
- property :term, Fixnum
53
- property :term_units, String, :default => 'years'
54
-
55
- property :weekday_hours, String
56
- property :saturday_hours, String
57
- property :sunday_hours, String
58
-
59
- property :offices, Fixnum
60
- property :desks, Fixnum
61
- property :conference_rooms, Fixnum
62
- property :bathrooms, Fixnum
63
-
64
- property :kitchen, Boolean
65
- property :showers, Boolean
66
- property :patio, Boolean
67
- property :reception_area, Boolean
68
- property :ready_to_move_in, Boolean
69
- property :furniture_available, Boolean
70
- property :natural_light, Boolean
71
- property :high_ceilings, Boolean
72
-
73
- property :created_at, DateTime, :serialize => :false
74
- property :updated_at, DateTime, :serialize => :false
75
- property :touched_at, DateTime, :serialize => :false
76
- property :leased_on, DateTime
77
- property :photography_requested_on, DateTime, :serialize => :false
78
-
79
- property :awesome_score, Fixnum
80
- property :awesome_needs, Array, :serialize => :if_present
81
- property :awesome_label, String
82
-
83
- property :flyer_id, Fixnum, :serialize => :if_present
84
- property :floorplan_id, Fixnum, :serialize => :if_present
85
-
86
- property :avatar_digest, String, :serialize => false
13
+ attribute :id, Fixnum, :serialize => :false
14
+ attribute :address_id, Fixnum, :serialize => :false
15
+ attribute :slug, String, :serialize => :false
16
+ attribute :use, String, :serialize => :if_present
17
+ attribute :account_id, Fixnum
18
+ attribute :private, Boolean, :default => false, :serialize => false
19
+ attribute :source, String
20
+ attribute :source_url, String
21
+ attribute :source_type, String, :serialize => :if_present
22
+ attribute :channel, String, :serialize => :if_present
23
+ attribute :photo_ids, Array, :serialize => :if_present
24
+
25
+ attribute :name, String
26
+ attribute :type, String, :default => 'lease'
27
+ attribute :workflow_state, String, :default => 'visible'
28
+ attribute :lease_state, String, :default => 'listed'
29
+ attribute :space_type, String, :default => 'unit'
30
+ attribute :unit, String
31
+ attribute :floor, Fixnum
32
+ attribute :description, String
33
+
34
+ attribute :size, Fixnum
35
+ attribute :maximum_contiguous_size, Fixnum
36
+ attribute :minimum_divisible_size, Fixnum
37
+
38
+ attribute :amenities, Hash
39
+ attribute :lease_terms, String
40
+ attribute :rate, Decimal
41
+ attribute :rate_units, String, :default => '/sqft/mo'
42
+ attribute :low_rate, Decimal, :serialize => :false
43
+ attribute :high_rate, Decimal, :serialize => :false
44
+ attribute :sublease_expiration, DateTime
45
+
46
+ attribute :forecast_rate_per_year, Decimal, :serialize => :false
47
+ attribute :forecast_rate_per_month, Decimal, :serialize => :false
48
+ attribute :forecast_rate_per_sqft_per_month, Decimal, :serialize => :false
49
+ attribute :forecast_rate_per_sqft_per_year, Decimal, :serialize => :false
50
+
51
+ attribute :available_on, DateTime
52
+ attribute :term, Fixnum
53
+ attribute :term_units, String, :default => 'years'
54
+
55
+ attribute :weekday_hours, String
56
+ attribute :saturday_hours, String
57
+ attribute :sunday_hours, String
58
+
59
+ attribute :offices, Fixnum
60
+ attribute :desks, Fixnum
61
+ attribute :conference_rooms, Fixnum
62
+ attribute :bathrooms, Fixnum
63
+
64
+ attribute :kitchen, Boolean
65
+ attribute :showers, Boolean
66
+ attribute :patio, Boolean
67
+ attribute :reception_area, Boolean
68
+ attribute :ready_to_move_in, Boolean
69
+ attribute :furniture_available, Boolean
70
+ attribute :natural_light, Boolean
71
+ attribute :high_ceilings, Boolean
72
+
73
+ attribute :created_at, DateTime, :serialize => :false
74
+ attribute :updated_at, DateTime, :serialize => :false
75
+ attribute :touched_at, DateTime, :serialize => :false
76
+ attribute :leased_on, DateTime
77
+ attribute :photography_requested_on, DateTime, :serialize => :false
78
+
79
+ attribute :awesome_score, Fixnum
80
+ attribute :awesome_needs, Array, :serialize => :if_present
81
+ attribute :awesome_label, String
82
+
83
+ attribute :flyer_id, Fixnum, :serialize => :if_present
84
+ attribute :floorplan_id, Fixnum, :serialize => :if_present
85
+
86
+ attribute :avatar_digest, String, :serialize => false
87
87
 
88
88
  # Counter Caches
89
- property :photos_count, Fixnum, :serialize => :false
89
+ attribute :photos_count, Fixnum, :serialize => :false
90
90
 
91
- attr_accessor :address, :agents, :account, :photos, :flyer, :floorplan, :videos, :similar_photos, :spaces, :primary_agent
91
+ attr_accessor :property, :address, :agents, :account, :photos, :flyer, :floorplan, :videos, :similar_photos, :spaces, :primary_agent
92
92
 
93
93
  def avatar(size='150x100#', protocol='http')
94
94
  if avatar_digest
@@ -380,6 +380,10 @@ class MLS::Listing::Parser < MLS::Parser
380
380
  @object.address = MLS::Address::Parser.build(address)
381
381
  end
382
382
 
383
+ def property=(property)
384
+ @object.property = MLS::Property::Parser.build(property)
385
+ end
386
+
383
387
  def agents=(agents)
384
388
  @object.agents = agents.map {|a| MLS::Account::Parser.build(a) }
385
389
  end