mls 0.14.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,15 +0,0 @@
1
- class MLS::PDF < MLS::Resource
2
-
3
- attribute :id, Fixnum
4
- attribute :digest, String
5
- attribute :file_url, String
6
- attribute :type, String
7
-
8
- def url(style='700x467#', protocol='http')
9
- "#{protocol}://#{MLS.image_host}/#{avatar_digest}.jpg?s=#{URI.escape(size)}"
10
- end
11
- end
12
-
13
- class MLS::PDF::Parser < MLS::Parser
14
-
15
- end
@@ -1,40 +0,0 @@
1
- require 'restclient'
2
-
3
- class MLS::Photo < MLS::Resource
4
-
5
- attribute :id, Fixnum
6
- attribute :digest, String
7
- attribute :created_at, DateTime
8
- attribute :updated_at, DateTime
9
- attribute :file_content_type, String
10
- attribute :file_name, String
11
- attribute :file_size, Fixnum
12
- attribute :url_template, String
13
- attribute :caption, String
14
- attribute :subject_id, Fixnum
15
-
16
- def url(style=nil, protocol='http')
17
- result = "#{protocol}://#{MLS.image_host}/#{digest}.jpg"
18
- if style
19
- result = result + "?s=#{URI.escape(style)}"
20
- end
21
-
22
- result
23
- end
24
-
25
- def self.create(attrs)
26
- attrs[:file].rewind
27
- url = MLS.url.dup
28
- url.user = nil
29
- url.path = "/photos"
30
- response = RestClient.post(url.to_s, {:photo => attrs}, MLS.headers)
31
- attrs[:file].close unless attrs[:file].closed?
32
-
33
- MLS::Photo::Parser.parse(response.body)
34
- end
35
-
36
- end
37
-
38
- class MLS::Photo::Parser < MLS::Parser
39
-
40
- end
@@ -1,114 +0,0 @@
1
- class MLS::Property < MLS::Resource
2
-
3
- attribute :id, Fixnum, :serialize => :false
4
- attribute :name, String, :serialize => :false
5
- attribute :slug, String, :serialize => :false
6
-
7
- attribute :latitude, Decimal
8
- attribute :longitude, Decimal
9
-
10
- attribute :description, String
11
- attribute :neighborhood, String
12
- attribute :constructed, Fixnum
13
- attribute :size, Fixnum
14
- attribute :floors, Fixnum
15
- attribute :leed_certification, String
16
- attribute :style, String
17
- attribute :height, Decimal
18
- attribute :lot_size, Decimal
19
-
20
- attribute :amenities, Hash
21
-
22
- # Counter caches
23
- attribute :listings_count, Fixnum, :serialize => :false
24
-
25
- attribute :avatar_digest, String, :serialize => false
26
-
27
- attr_accessor :listings, :addresses, :photos, :videos
28
-
29
- # should include an optional use address or no_image image
30
- def avatar(size='100x200#', protocol='http')
31
- params = {
32
- :size => size,
33
- :format => 'png',
34
- :sensor => false,
35
- :location => [formatted_address],
36
- :fov => 120
37
- }
38
-
39
- if avatar_digest
40
- "#{protocol}://#{MLS.image_host}/#{avatar_digest}.jpg?s=#{URI.escape(size)}"
41
- else
42
- params[:size] = params[:size].match(/\d+x\d+/)[0]
43
- "#{protocol}://maps.googleapis.com/maps/api/streetview?" + params.map{|k,v| k.to_s + '=' + URI.escape(v.to_s) }.join('&')
44
- end
45
- end
46
-
47
- def save
48
- MLS.put("/properties/#{id}", {:address => to_hash}, 400) do |response, code|
49
- if code == 200 || code == 400
50
- MLS::Property::Parser.update(self, response.body)
51
- code == 200
52
- else
53
- raise MLS::Exception::UnexpectedResponse, code
54
- end
55
- end
56
- end
57
-
58
- def to_hash
59
- hash = super
60
- hash[:photo_ids] = photos.map(&:id) if photos
61
- hash[:videos_attributes] = videos.map(&:to_hash) unless videos.blank?
62
- hash
63
- end
64
-
65
- def to_param
66
- slug
67
- end
68
-
69
- class << self
70
-
71
- def find(id)
72
- response = MLS.get("/properties/#{id}")
73
- MLS::Property::Parser.parse(response.body)
74
- end
75
-
76
- # currently supported options are :include, :where, :limit, :offset
77
- def all(options={})
78
- response = MLS.get('/properties', options)
79
- MLS::Property::Parser.parse_collection(response.body)
80
- end
81
-
82
- def amenities
83
- @amenities ||= Yajl::Parser.new(:symbolize_keys => true).parse(MLS.get('/properties/amenities').body)
84
- end
85
-
86
- end
87
-
88
- end
89
-
90
-
91
- class MLS::Property::Parser < MLS::Parser
92
-
93
- def listings=(listings)
94
- @object.listings = listings.map { |data|
95
- listing = MLS::Listing::Parser.build(data)
96
- listing.address = @object
97
- listing
98
- }
99
- end
100
-
101
- def photos=(photos)
102
- @object.photos = photos.map {|p| MLS::Photo::Parser.build(p)}
103
- end
104
-
105
- def videos=(videos)
106
- @object.videos = videos.map do |video|
107
- MLS::Video::Parser.build(video)
108
- end
109
- end
110
-
111
- def addresses=(addresses)
112
- @object.addresses = addresses.map {|a| MLS::Property::Parser.build(addresses)}
113
- end
114
- end
@@ -1,56 +0,0 @@
1
- class MLS::Region < MLS::Resource
2
-
3
- attribute :id, Fixnum
4
- attribute :name, String
5
- attribute :proper_name, String
6
- attribute :common_name, String
7
- attribute :code, String
8
- attribute :type, String
9
- attribute :source, String
10
- attribute :minimum_zoom, Fixnum
11
- attribute :maximum_zoom, Fixnum
12
- attribute :slug, String
13
- attribute :geometry, Hash
14
- attribute :envelope, Hash
15
- attribute :children, Hash
16
-
17
- # Counter caches
18
- attribute :properties_count, Fixnum
19
-
20
- class << self
21
-
22
- def find(id)
23
- response = MLS.get("/regions/#{id}")
24
- MLS::Region::Parser.parse(response.body)
25
- end
26
-
27
- def all(options={})
28
- response = MLS.get('/regions', options)
29
- MLS::Region::Parser.parse_collection(response.body)
30
- end
31
-
32
- end
33
-
34
- def name
35
- common_name || proper_name
36
- end
37
-
38
- def bounds
39
- return nil unless envelope
40
- n, e, s, w = nil, nil, nil, nil
41
- envelope[:coordinates][0].each do |c|
42
- lon, lat = *c
43
- n = lat if !n || lat > n
44
- e = lon if !e || lon > e
45
- s = lat if !s || lat < s
46
- w = lon if !w || lon < w
47
- end
48
- [n, e, s, w]
49
- end
50
-
51
- end
52
-
53
-
54
- class MLS::Region::Parser < MLS::Parser
55
-
56
- end
@@ -1,54 +0,0 @@
1
- class MLS::Tour < MLS::Resource
2
- attribute :id, Fixnum
3
- attribute :declined, Boolean
4
- attribute :client_id, Fixnum
5
- attribute :agent_id, Fixnum
6
- attribute :listing_id, Fixnum
7
- attribute :comments, String
8
- attribute :agent_comments, String, :serialize => :if_present
9
- attribute :token, String, :serialize => :false
10
- attribute :created_at, DateTime, :serialize => :false
11
- attribute :updated_at, DateTime, :serialize => :false
12
-
13
- attr_accessor :client, :listing
14
-
15
- def decline(notes=nil)
16
- self.agent_comments = notes
17
- MLS.post("/tours/#{token}/decline", {:agent_comments => notes})
18
- end
19
-
20
- def declined?
21
- declined
22
- end
23
-
24
- class << self
25
- def get_all_for_account
26
- response = MLS.get('/account/tours')
27
- MLS::Tour::Parser.parse_collection(response.body)
28
- end
29
-
30
- def find_by_token(token)
31
- response = MLS.get("/tours/#{token}")
32
- MLS::Tour::Parser.parse(response.body)
33
- end
34
-
35
- def create(listing_id, account, tour={})
36
- params = {:account => account, :tour => tour}
37
- response = MLS.post("/listings/#{listing_id}/tour", params)
38
- return MLS::Tour::Parser.parse(response.body)
39
- end
40
- end
41
-
42
- end
43
-
44
- class MLS::Tour::Parser < MLS::Parser
45
-
46
- def listing=(listing)
47
- @object.listing = MLS::Listing::Parser.build(listing)
48
- end
49
-
50
- def client=(account)
51
- @object.client = MLS::Account::Parser.build(account)
52
- end
53
-
54
- end
@@ -1,18 +0,0 @@
1
- class MLS::Video < MLS::Resource
2
- attribute :id, Fixnum
3
- attribute :vts_key, String
4
- attribute :video_type, String
5
- attribute :subject_type, String, :serialize => false
6
- attribute :created_at, DateTime, :serialize => :if_present
7
- attribute :updated_at, DateTime, :serialize => :if_present
8
-
9
- attribute :photo_id, Fixnum, :serialize => :if_present
10
-
11
- attr_accessor :photo
12
- end
13
-
14
- class MLS::Video::Parser < MLS::Parser
15
- def photo=(photo)
16
- @object.photo = MLS::Photo::Parser.build(photo)
17
- end
18
- end
@@ -1,74 +0,0 @@
1
- class MLS::Parser
2
-
3
- attr_reader :object
4
-
5
- def initialize(object=nil, persisted=true)
6
- @object = object || self.class.object_class.new({}, persisted)
7
- end
8
-
9
- def parse(data)
10
- attributes = extract_attributes(data)
11
- update_attributes(attributes)
12
- object
13
- end
14
-
15
- def build(attributes)
16
- update_attributes(attributes)
17
- object
18
- end
19
-
20
- def update_attributes(attributes)
21
- attributes.each {|k,v| self.send("#{k}=".to_sym, v) } if attributes
22
- end
23
-
24
- def self.parse(data)
25
- self.new.parse(data)
26
- end
27
-
28
- # TODO: TEST ME
29
- def self.build_collection(hash, options={})
30
- root = options[:collection_root_element] || collection_root_element
31
- collection = []
32
- hash[root].each do |attrs|
33
- collection << build(attrs)
34
- end
35
- collection
36
- end
37
-
38
- def self.parse_collection(data, options={})
39
- build_collection(extract_attributes(data), options)
40
- end
41
-
42
- def self.build(attributes)
43
- self.new.build(attributes)
44
- end
45
-
46
- def self.update(object, data)
47
- self.new(object).parse(data)
48
- end
49
-
50
- def method_missing(method, *args, &block)
51
- object.__send__(method, *args, &block) if object.methods.include?(method)
52
- end
53
-
54
- def extract_attributes(data)
55
- Yajl::Parser.new(:symbolize_keys => true).parse(data)
56
- end
57
-
58
- def self.extract_attributes(data)
59
- Yajl::Parser.new(:symbolize_keys => true).parse(data)
60
- end
61
-
62
- def self.object_class
63
- @object_class ||= ActiveSupport::Inflector.constantize(self.to_s.sub('::Parser',''))
64
- end
65
-
66
- def self.root_element
67
- object_class.root_element
68
- end
69
-
70
- def self.collection_root_element
71
- object_class.collection_root_element
72
- end
73
-
74
- end
@@ -1,99 +0,0 @@
1
- class MLS::Resource
2
-
3
- attr_reader :persisted
4
- attr_accessor :errors
5
-
6
- def self.inherited(subclass)
7
- subclass.extend(MLS::Model)
8
- end
9
-
10
- def initialize(attributes = {}, persisted = false)
11
- @persisted = persisted
12
- @errors = {}
13
-
14
- set_default_values
15
- update_attributes(attributes)
16
- end
17
-
18
- def new_record?
19
- !@persisted
20
- end
21
-
22
- def persisted?
23
- @persisted
24
- end
25
-
26
- def save
27
- new_record? ? create : update
28
- end
29
-
30
- def save!
31
- new_record? ? create! : update!
32
- end
33
-
34
- def update!
35
- update || raise(MLS::Exception::RecordInvalid)
36
- end
37
-
38
- def create!
39
- create || raise(MLS::Exception::RecordInvalid)
40
- end
41
-
42
- def ==(other)
43
- self.class == other.class && attributes_for_comparison == other.attributes_for_comparison
44
- end
45
-
46
- # Attributes ===================================================================================================
47
-
48
- def attributes
49
- self.class.attributes
50
- end
51
-
52
- def attributes_for_comparison
53
- compare = {}
54
- attributes.reject{ |k, p| attributes_excluded_from_comparison.include?(k) }.each do |k, p|
55
- compare[k] = self.send(attributes[k].name.to_sym)
56
- end
57
- compare
58
- end
59
-
60
- def attributes_excluded_from_comparison
61
- self.class.attributes_excluded_from_comparison
62
- end
63
-
64
- def set_default_values
65
- attributes.each do |name, attribute|
66
- self.send("#{name}=".to_sym, attribute.default) if attribute.default
67
- end
68
- end
69
-
70
- def update_attributes(attrs)
71
- attrs.each { |k, v| self.send("#{k}=".to_sym, v) } unless attrs.nil?
72
- end
73
-
74
- # Combo Breaker ================================================================================================
75
-
76
- def to_hash
77
- hash = {}
78
-
79
- attributes.each do |name, attribute|
80
- serialize = attribute.options[:serialize]
81
- serialize = :always if serialize.nil?
82
- case serialize
83
- when :always
84
- hash[name] = attribute.dump(self.send(name))
85
- when :if_present
86
- hash[name] = attribute.dump(self.send(name)) if self.send(name)
87
- end
88
- end
89
-
90
- hash
91
- end
92
-
93
- #== for rails form stuff
94
-
95
- def to_key
96
- persisted? ? [id] : nil
97
- end
98
-
99
- end