mls 1.4.3 → 1.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb0e3846ad2100b2167d386911bf6e4d504ffb47
4
- data.tar.gz: f413e79ba06c41ccb8d105d88cae096c338374de
3
+ metadata.gz: 9caa8aa44855ec88845d59e8732212c33e9ae86f
4
+ data.tar.gz: e443bbd96ee37784f7bd360d185cafab43e4d0d4
5
5
  SHA512:
6
- metadata.gz: b9d84713798402d9da3f892e09c036918432c965ffdd2030ccc35286033b0dec2022419d65e2ea049355c41c5aa6c816afce9e31ff3243f6b8891881b96fa5a0
7
- data.tar.gz: ce4f8326d2255448f5513fffc31a8438bae12d7c68ff6e781831e523634a9bc51c871fb1ac95161471efc7742f0d5528cb7190a4b5486da42438ce76349d8307
6
+ metadata.gz: c0b278d87cf5e782045105c1f8461a8feda501f74da7af7bc8cc33a14d1d38e614632073609b208f1f6aaf978f029a0680f11e6fa10cfc088374fb6640581ef5
7
+ data.tar.gz: 19ebd1f220371778d1c74a5ebfde587bfea7c076f62fac80c912d6b966a34adc710ed459b557bf58bae3bb03466e6016c4fde716bee6ab8c21d423d22048e699
data/lib/mls.rb CHANGED
@@ -48,21 +48,97 @@ module MLS::Slugger
48
48
 
49
49
  extend ActiveSupport::Concern
50
50
 
51
- module ClassMethods
51
+ included do
52
+ class_attribute :slugger
53
+ send :include, MLS::Slugger::ActiveRecordBaseSluggerExtension
54
+ relation.class.send :include, MLS::Slugger::ActiveRecordRelationSluggerExtension
55
+ end
52
56
 
53
- def find(*ids)
54
- friendly = -> (id) { id.respond_to?(:to_i) && id.to_i.to_s != id.to_s }
55
- return super if ids.size > 1 || !ids.all? { |x| friendly.call(x) }
57
+ module ActiveRecordBaseSluggerExtension
58
+ extend ActiveSupport::Concern
56
59
 
57
- find_by_slug!(ids)
60
+ # TODO: Test
61
+ def to_param
62
+ slug? ? slug : super
58
63
  end
59
64
 
60
- end
65
+ def set_slug
66
+ generated_slug = if self.slugger[:proc].is_a?(Proc)
67
+ if (self.slugger[:proc].arity == 1)
68
+ self.slugger[:proc].call(self)
69
+ else
70
+ self.slugger[:proc].call
71
+ end
72
+ else
73
+ send(self.slugger[:proc])
74
+ end
75
+ generated_slug = generated_slug ? generated_slug.split('/').map(&:parameterize).join('/') : nil
76
+
77
+ if self.slugger[:options][:history]
78
+ self.slugger[:slug_was] = self.slug
79
+ end
80
+
81
+ if [:before_validation, :after_validation, :before_save, :before_create].include?(self.slugger[:options][:trigger])
82
+ self.slug = generated_slug
83
+ else
84
+ update_column(:slug, generated_slug) if slug != generated_slug
85
+ end
86
+ end
87
+
88
+ module ClassMethods
89
+
90
+ def slug(method, options={}, &block)
91
+ options = options.with_indifferent_access
92
+ options[:trigger] ||= :after_save
93
+ self.slugger = { :proc => method || block, :options => options }
94
+ self.send(options[:trigger], :set_slug)
95
+ self.send(:include, Slugger::History) if options[:history]
96
+ end
97
+
98
+ def find(*ids)
99
+ friendly = -> (id) { id.respond_to?(:to_i) && id.to_i.to_s != id.to_s }
100
+ return super if ids.size > 1 || !ids.all? { |x| friendly.call(x) }
101
+
102
+ find_by_slug!(ids.first)
103
+ end
104
+
105
+ end
61
106
 
62
- def to_param
63
- slug
64
107
  end
65
108
 
109
+ module ActiveRecordRelationSluggerExtension
110
+
111
+ def find_one(id)
112
+ friendly = id.respond_to?(:to_i) && id.to_i.to_s != id.to_s
113
+ friendly ? find_by_slug!(id) : super
114
+ end
115
+
116
+ def find_some(ids)
117
+ friendly = -> (id) { id.respond_to?(:to_i) && id.to_i.to_s != id.to_s }
118
+ return super if !ids.all? { |x| friendly.call(x) }
119
+
120
+ result = where(table['slug'].in(ids)).to_a
121
+
122
+ expected_size =
123
+ if limit_value && ids.size > limit_value
124
+ limit_value
125
+ else
126
+ ids.size
127
+ end
128
+
129
+ # 11 ids with limit 3, offset 9 should give 2 results.
130
+ if offset_value && (ids.size - offset_value < expected_size)
131
+ expected_size = ids.size - offset_value
132
+ end
133
+
134
+ if result.size == expected_size
135
+ result
136
+ else
137
+ raise_record_not_found_exception!(ids, result.size, expected_size)
138
+ end
139
+ end
140
+
141
+ end
66
142
  end
67
143
 
68
144
  module MLS::Avatar
@@ -74,6 +150,7 @@ module MLS::Avatar
74
150
  end
75
151
 
76
152
  def avatar_url(options={})
153
+ return nil unless avatar_hash_key
77
154
 
78
155
  options.reverse_merge!({
79
156
  :style => nil,
@@ -6,6 +6,7 @@ class Account < MLS::Model
6
6
  has_one :lead, foreign_key: :account_id
7
7
 
8
8
  belongs_to :organization
9
+ belongs_to :green_sheet, :foreign_key => :green_sheet_uuid
9
10
 
10
11
  has_many :tasks
11
12
  has_many :sources
@@ -13,14 +14,14 @@ class Account < MLS::Model
13
14
 
14
15
  has_and_belongs_to_many :regions, :foreign_key => :agent_id
15
16
 
16
- has_many :email_addresses, :dependent => :destroy do
17
+ has_many :email_addresses do
17
18
  def primary
18
19
  # For cases where the number is not primary we order
19
20
  order(:primary => :desc).first
20
21
  end
21
22
  end
22
23
 
23
- has_many :phones, dependent: :destroy do
24
+ has_many :phones do
24
25
 
25
26
  def primary
26
27
  # For cases where the number is not primary we order
@@ -44,5 +45,10 @@ class Account < MLS::Model
44
45
  phones.primary.try(:number)
45
46
  end
46
47
  end
48
+
49
+ def company_name
50
+ return organization.name if organization
51
+ return company
52
+ end
47
53
 
48
54
  end
@@ -1,4 +1,4 @@
1
1
  class Address < MLS::Model
2
2
 
3
-
3
+ belongs_to :property
4
4
  end
@@ -1,12 +1,18 @@
1
1
  class CoworkingSpace < MLS::Model
2
2
  include MLS::Slugger
3
-
4
- belongs_to :unit
5
-
6
- has_one :address
7
- has_one :property, through: :unit
8
-
9
- has_many :spaces
10
- has_many :addresses
3
+ include MLS::Avatar
4
+
5
+ belongs_to :organization
6
+ belongs_to :property
7
+ has_many :image_orderings, as: :subject
8
+ has_many :photos, through: :image_orderings, source: :image
9
+ has_many :spaces
10
+ has_many :addresses, :through => :property
11
+
12
+ def name
13
+ output = organization.name
14
+ output += " - " + read_attribute(:name) if read_attribute(:name)
15
+ output
16
+ end
11
17
 
12
18
  end
@@ -5,9 +5,9 @@ class Event < MLS::Model
5
5
  belongs_to :account
6
6
  belongs_to :task
7
7
 
8
- has_many :event_actions, :dependent => :destroy
8
+ has_many :event_actions
9
9
 
10
- has_many :regards, :dependent => :destroy
10
+ has_many :regards
11
11
 
12
12
  def actions
13
13
  event_actions.map(&:action)
@@ -0,0 +1,7 @@
1
+ class Geometry < MLS::Model
2
+
3
+ self.inheritance_column = nil
4
+
5
+ belongs_to :subject, polymorphic: true
6
+
7
+ end
@@ -0,0 +1,5 @@
1
+ class GreenSheet < MLS::Model
2
+
3
+ has_one :account, :foreign_key => :green_sheet_uuid
4
+
5
+ end
@@ -19,8 +19,7 @@ class Listing < MLS::Model
19
19
 
20
20
  belongs_to :flyer, :class_name => 'Document'
21
21
  belongs_to :unit
22
-
23
- has_one :property, :through => :unit
22
+ belongs_to :property
24
23
 
25
24
  has_many :photos, -> { order(:order => :asc) }, :as => :subject, :inverse_of => :subject
26
25
 
@@ -5,7 +5,7 @@ class Property < MLS::Model
5
5
 
6
6
  has_many :units
7
7
  has_many :references, as: :subject
8
- has_many :listings, :through => :units
8
+ has_many :listings
9
9
  has_many :localities
10
10
  has_many :regions, :through => :localities
11
11
  has_many :image_orderings, as: :subject
@@ -29,29 +29,104 @@ class Property < MLS::Model
29
29
  addresses.find(&:primary)
30
30
  end
31
31
 
32
+ def longitude
33
+ location.x
34
+ end
35
+
36
+ def latitude
37
+ location.y
38
+ end
39
+
40
+ def automated_description
41
+ external_data['narrativescience.com']
42
+ end
43
+
44
+ def internet_providers
45
+ data = []
46
+
47
+ if external_data['broadbandmap.gov']
48
+ if external_data['broadbandmap.gov']['wirelineServices']
49
+ external_data['broadbandmap.gov']['wirelineServices'].sort_by{|p| p['technologies'].sort_by{|t| t['maximumAdvertisedDownloadSpeed']}.reverse.first['maximumAdvertisedDownloadSpeed']}.reverse.each do |provider|
50
+ tech = provider['technologies'].sort_by{|t| t['maximumAdvertisedDownloadSpeed']}.reverse.first
51
+ speedcase = -> (speedCode) {
52
+ case speedCode
53
+ when 1 then '200 kbps'
54
+ when 2 then '768 kbps'
55
+ when 3 then '1.5 Mb/s'
56
+ when 4 then '3 Mb/s'
57
+ when 5 then '6 Mb/s'
58
+ when 6 then '10 Mb/s'
59
+ when 7 then '25 Mb/s'
60
+ when 8 then '50 Mb/s'
61
+ when 9 then '100 Mb/s'
62
+ when 10 then '1 Gb/s'
63
+ when 11 then '1 Gb/s+'
64
+ else 'Unknown'
65
+ end
66
+ }
67
+
68
+ data << {
69
+ provider_name: provider['doingBusinessAs'] || provider['providerName'],
70
+ provider_url: provider['providerURL'],
71
+ technology: case tech['technologyCode']
72
+ when 10 then 'DSL'
73
+ when 20 then 'DSL'
74
+ when 30 then 'Copper Wireline'
75
+ when 40 then 'Cable'
76
+ when 41 then 'Cable'
77
+ when 50 then 'Fiber'
78
+ when 90 then 'Power Line'
79
+ else 'Other'
80
+ end,
81
+ bandwidth: {
82
+ up: speedcase.call(tech['maximumAdvertisedUploadSpeed']),
83
+ down: speedcase.call(tech['maximumAdvertisedDownloadSpeed'])
84
+ }
85
+ }
86
+ end
87
+ end
88
+ end
89
+
90
+ data
91
+ end
92
+
93
+ def closest_region
94
+ region = neighborhood_region
95
+ region ||= city_region
96
+ region ||= market
97
+ region
98
+ end
99
+
32
100
  def neighborhood_region
33
- params = {:query => address.neighborhood} if address.try(:neighborhood)
34
- params ||= {:query => neighborhood} if neighborhood
35
- params ||= {:type => "Neighborhood"}
36
- fetch_region(params)
101
+ return @neighborhood_region if defined? @neighborhood_region
102
+ params = {:query => neighborhood} if neighborhood
103
+ params = {:type => "Neighborhood"}
104
+ @neighborhood_region = fetch_region(params)
37
105
  end
38
106
 
39
107
  def city_region
40
- fetch_region(:type => "City")
108
+ return @city_region if defined? @city_region
109
+ @city_region = fetch_region(:type => "City")
41
110
  end
42
111
 
43
112
  def market
44
- fetch_region(:is_market => true)
113
+ return @market if defined? @market
114
+ @market = fetch_region(:is_market => true)
45
115
  end
46
116
 
47
- def target_region
48
- fetch_region(:target => true)
117
+ def flagship
118
+ return @flagship if defined? @flagship
119
+ @flagship = fetch_region(:is_flagship => true)
49
120
  end
50
121
 
51
122
  def fetch_region(params)
52
123
  if regions.loaded?
53
124
  params = params.map{|k,v| [k, v]}
54
- regions.to_a.find{|r| r[params[0][0]] == params[0][1]}
125
+ if params[0][0] == :query
126
+ regions.to_a.find{|r| r.name == params[0][1]}
127
+ else
128
+ regions.to_a.find{|r| r[params[0][0]] == params[0][1]}
129
+ end
55
130
  else
56
131
  regions.where(params).first
57
132
  end
@@ -6,7 +6,12 @@ class Region < MLS::Model
6
6
 
7
7
  belongs_to :cover_photo, :class_name => 'Image'
8
8
  belongs_to :market, :class_name => 'Region'
9
-
9
+ belongs_to :flagship, :class_name => 'Region'
10
+
11
+ has_one :geometry, as: :subject
12
+ has_many :stats, as: :subject
13
+
14
+ has_and_belongs_to_many :organizations
10
15
  has_and_belongs_to_many :parents, :join_table => 'regions_regions', :class_name => 'Region', :foreign_key => 'child_id', :association_foreign_key => 'parent_id'
11
16
  has_and_belongs_to_many :children, :join_table => 'regions_regions', :class_name => 'Region', :foreign_key => 'parent_id', :association_foreign_key => 'child_id'
12
17
 
@@ -18,16 +23,6 @@ class Region < MLS::Model
18
23
  end
19
24
  end
20
25
 
21
- def target
22
- return @target if @target
23
- @target = children.where(:target => true).first
24
- @target ||= market.try(:target)
25
- @target ||= market
26
- @target ||= self
27
-
28
- @target
29
- end
30
-
31
26
  def cover_photo_url(options={})
32
27
 
33
28
  options.reverse_merge!({
@@ -1,5 +1,7 @@
1
1
  class Space < MLS::Model
2
2
 
3
- belongs_to :coworking_space
3
+ belongs_to :coworking_space
4
+ has_many :image_orderings, as: :subject
5
+ has_many :photos, through: :image_orderings, source: :image
4
6
 
5
7
  end
@@ -0,0 +1,3 @@
1
+ class Stat < MLS::Model
2
+ belongs_to :subject, polymorphic: true
3
+ end
@@ -8,7 +8,7 @@ class Unit < MLS::Model
8
8
  belongs_to :floorplan, :class_name => 'Document'
9
9
 
10
10
  has_many :listings
11
- has_many :image_orderings, as: :subject, dependent: :destroy
11
+ has_many :image_orderings, as: :subject
12
12
  has_many :photos, through: :image_orderings, source: :image
13
13
  # has_many :photos, -> { order(:order => :asc) }, :as => :subject, :inverse_of => :subject
14
14
 
@@ -7,7 +7,7 @@ class Vendor < MLS::Model
7
7
  has_and_belongs_to_many :regions
8
8
  belongs_to :account
9
9
 
10
- has_many :image_orderings, as: :subject, dependent: :destroy
10
+ has_many :image_orderings, as: :subject
11
11
  has_many :photos, through: :image_orderings, source: :image
12
12
 
13
13
  end
@@ -0,0 +1,3 @@
1
+ class View < MLS::Model
2
+ belongs_to :subject, polymorphic: true
3
+ end
@@ -1,7 +1,12 @@
1
1
  class Webpage < MLS::Model
2
2
 
3
- has_one :task, as: :subject
3
+ belongs_to :source
4
+ has_many :tasks, as: :subject
4
5
 
5
6
  validates :url, presence: true
6
7
 
8
+ def name
9
+ url.match(/^(?:https?:\/\/)?(?:www\.)?([^\/]+)/)[1]
10
+ end
11
+
7
12
  end
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "mls"
6
- s.version = '1.4.3'
6
+ s.version = '1.5.0'
7
7
  s.authors = ["Jon Bracy", "James R. Bracy"]
8
8
  s.email = ["jon@42floors.com", "james@42floors.com"]
9
9
  s.homepage = "http://mls.42floors.com"
@@ -31,5 +31,6 @@ Gem::Specification.new do |s|
31
31
  s.add_development_dependency 'sdoc-templates-42floors'
32
32
 
33
33
  # Runtime
34
- s.add_runtime_dependency 'sunstone'
34
+ s.add_runtime_dependency 'rgeo', '>= 0.4.0'
35
+ s.add_runtime_dependency 'sunstone', '>= 2.0.1'
35
36
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mls
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-25 00:00:00.000000000 Z
12
+ date: 2015-10-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -165,20 +165,34 @@ dependencies:
165
165
  - - ">="
166
166
  - !ruby/object:Gem::Version
167
167
  version: '0'
168
+ - !ruby/object:Gem::Dependency
169
+ name: rgeo
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: 0.4.0
175
+ type: :runtime
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: 0.4.0
168
182
  - !ruby/object:Gem::Dependency
169
183
  name: sunstone
170
184
  requirement: !ruby/object:Gem::Requirement
171
185
  requirements:
172
186
  - - ">="
173
187
  - !ruby/object:Gem::Version
174
- version: '0'
188
+ version: 2.0.1
175
189
  type: :runtime
176
190
  prerelease: false
177
191
  version_requirements: !ruby/object:Gem::Requirement
178
192
  requirements:
179
193
  - - ">="
180
194
  - !ruby/object:Gem::Version
181
- version: '0'
195
+ version: 2.0.1
182
196
  description: Ruby library for integrating with the 42Floors MLS
183
197
  email:
184
198
  - jon@42floors.com
@@ -203,6 +217,8 @@ files:
203
217
  - lib/mls/email_address.rb
204
218
  - lib/mls/event.rb
205
219
  - lib/mls/event_action.rb
220
+ - lib/mls/geometry.rb
221
+ - lib/mls/green_sheet.rb
206
222
  - lib/mls/image_ordering.rb
207
223
  - lib/mls/inquiry.rb
208
224
  - lib/mls/lead.rb
@@ -219,11 +235,13 @@ files:
219
235
  - lib/mls/slug.rb
220
236
  - lib/mls/source.rb
221
237
  - lib/mls/space.rb
238
+ - lib/mls/stat.rb
222
239
  - lib/mls/task.rb
223
240
  - lib/mls/time_log.rb
224
241
  - lib/mls/unit.rb
225
242
  - lib/mls/use.rb
226
243
  - lib/mls/vendor.rb
244
+ - lib/mls/view.rb
227
245
  - lib/mls/webpage.rb
228
246
  - mls.gemspec
229
247
  - test/fixtures/flyer.pdf