caboose-rets 0.0.69 → 0.0.70

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,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjRhYzQ1ZWY3YjMzZmFhNzYwZjFhNTUyNzk2NjU5OWRlZjNhN2FiNw==
4
+ MWExNTE4ZTRhZDM1MDUxY2YwNzllZTA4ZjgxMTJhZjNmNjQ2ZDdhNg==
5
5
  data.tar.gz: !binary |-
6
- ZmNmMzg1NDMzZTQxZGViZWE0OTZmNzBjYzFkY2ZhZjQ5MGRiYzA1Mw==
6
+ ZmM4YmY1MWM3MWUxOGExMjY2M2NhYmVlYzA1MWRhOWVmMWE1ZTY2OA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NzE2YzRjODQ2MjU2ZGE1YzA2MTRmZjI2OGMxMWVmNzg2YWQzNGYwMmE0NGVm
10
- ZDc0MzJmN2E5YjZjMTkwOTgwZTZmNzk5NWExYmVmODRkMjg5NjUwZDIxNzhj
11
- NWQ3NDkwZDJmYTIyN2EzYTIwZWI3MWZjY2YwMzY0NGI3NDI4ZTI=
9
+ MjcwNzQyZjkwMjg5NTYwN2M1ODkxMDhkNzQxNWQ5ZGVlYTQ5ZDZkYjkxY2Qy
10
+ YzAxZDAxMTFmNjI4Y2U0ODYzNmQyM2YwMzIyOGUzNjkzNDUwMWRlNjFkMTdl
11
+ OGVhN2QxMjZmZDRhNWVlNzI2MDJhNjRjYzRiZDEyNTg4ZDU2Mjk=
12
12
  data.tar.gz: !binary |-
13
- NzFiMDQ1ZGI5NTA0NWI1NTI3NmFmYjgwNTBiMDZhY2I2NjI3YjllZGM4NDlh
14
- MzI0NmU4YmYzODIxYWMxOWExMGU0YmM2ODFkMmQ4MGQxOWQ2NzIzYmU0MzY0
15
- NzEwZDIyNmVlZDEzNTE5OWEzYzY3MTNiZjVjMmUxNGZkNGU1OTk=
13
+ OGYzODJjYTBmNzQwMTI4MWUyZDBkNDMwMGU3ZmY1YmU5MjdjZGE5ZDMyMzZi
14
+ YzI0NDgwNmVjZTQ5NDE5ODY4NzZmYTEzODIwM2I1YmQ4N2JlMWMwMzgwMmM4
15
+ ZTY0OTg4OTcxNWI5MWY2MjJhYTllZTE0ZmUzYTI1Y2U3Y2NhMmM=
@@ -102,9 +102,9 @@ module CabooseRets
102
102
  :content_type => m.image_content_type,
103
103
  :file_size => m.image_file_size,
104
104
  :update_at => m.image_updated_at,
105
- :tiny_url => m.image.url(:tiny),
106
- :thumb_url => m.image.url(:thumb),
107
- :large_url => m.image.url(:large)
105
+ :tiny_url => m.image_url(:tiny),
106
+ :thumb_url => m.image_url(:thumb),
107
+ :large_url => m.image_url(:large)
108
108
  },
109
109
  :file => {
110
110
  :file_name => m.file_file_name,
@@ -76,5 +76,13 @@ class CabooseRets::Agent < ActiveRecord::Base
76
76
  self.photo_date_modified = data['PHOTO_DATE_MODIFIED']
77
77
  #self.photo_url = ""
78
78
  end
79
+
80
+ def image_url(style)
81
+ if CabooseRets::use_hosted_images == true
82
+ return "#{CabooseRets::agents_base_url}/#{self.image_file_name}"
83
+ end
84
+ return "" if self.image.nil?
85
+ return self.image.url(style)
86
+ end
79
87
 
80
88
  end
@@ -18,7 +18,7 @@ class CabooseRets::Media < ActiveRecord::Base
18
18
  self.date_modified = data['DATE_MODIFIED']
19
19
  self.file_name = data['FILE_NAME']
20
20
  self.media_id = data['MEDIA_ID']
21
- self.media_order = data['MEDIA_ORDER']
21
+ self.media_order = data['MEDIA_ORDER'].to_i
22
22
  self.media_remarks = data['MEDIA_REMARKS']
23
23
  self.media_type = data['MEDIA_TYPE']
24
24
  self.mls_acct = data['MLS_ACCT']
@@ -122,5 +122,13 @@ class CabooseRets::Media < ActiveRecord::Base
122
122
 
123
123
  return true
124
124
  end
125
-
125
+
126
+ def image_url(style)
127
+ if CabooseRets::use_hosted_images == true
128
+ return "#{CabooseRets::media_base_url}/#{self.file_name}"
129
+ end
130
+ return "" if self.image.nil?
131
+ return self.image.url(style)
132
+ end
133
+
126
134
  end
@@ -78,16 +78,22 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
78
78
  :timeout => -1
79
79
  }
80
80
  obj = nil
81
- self.client.search(params) do |data|
82
- obj = self.get_instance_with_id(class_type, data)
83
- if obj.nil?
84
- self.log("Error: object is nil")
85
- self.log(data.inspect)
86
- next
81
+ begin
82
+ self.client.search(params) do |data|
83
+ obj = self.get_instance_with_id(class_type, data)
84
+ if obj.nil?
85
+ self.log("Error: object is nil")
86
+ self.log(data.inspect)
87
+ next
88
+ end
89
+ obj.parse(data)
90
+ obj.save
87
91
  end
88
- obj.parse(data)
89
- obj.save
92
+ rescue RETS::HTTPError => err
93
+ self.log "Import error for #{class_type}: #{query}"
94
+ self.log err.message
90
95
  end
96
+
91
97
  end
92
98
 
93
99
  def self.get_instance_with_id(class_type, data)
@@ -204,7 +210,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
204
210
  self.update_coords(p)
205
211
  end
206
212
 
207
- def self.import_office(lo_code, save_images = true)
213
+ def self.import_office(lo_code, save_images = true)
208
214
  self.import('OFF', "(LO_LO_CODE=*#{lo_code}*)")
209
215
  office = CabooseRets::Office.where(:lo_code => lo_code.to_s).first
210
216
  self.download_office_image(office) if save_images == true
@@ -221,97 +227,43 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
221
227
  end
222
228
 
223
229
  def self.import_media(id, save_images = true)
224
- self.import('GFX', "((MEDIA_ID=#{id}+),(MEDIA_ID=#{id}-))")
225
- #self.client.get_object(:resource => :Property, :type => :Photo, :location => true, :id => p.id) do |headers, content|
226
- #
227
- # # Find the associated media record for the image
228
- # filename = File.basename(headers['location'])
229
- # m = CabooseRets::Media.where(:mls_acct => p.mls_acct, :file_name => filename).first
230
- #
231
- # if m.nil?
232
- # self.log("Can't find media record for #{p.mls_acct} #{filename}.")
233
- # else
234
- # m.image = URI.parse(headers['location'])
235
- # media << m
236
- # #m.save
237
- # end
238
- #end
230
+ self.import('GFX', "((MEDIA_ID=#{id}+),(MEDIA_ID=#{id}-))")
239
231
  end
240
232
 
241
233
  #=============================================================================
242
234
  # Images
243
235
  #=============================================================================
244
-
236
+
245
237
  def self.download_property_images(p, save_images = true)
246
- self.refresh_property_media(p)
247
238
  return if save_images == false
248
-
249
- self.log("-- Downloading images and resizing for #{p.mls_acct}")
250
- media = []
251
- self.client.get_object(:resource => :Property, :type => :Photo, :location => true, :id => p.id) do |headers, content|
252
-
253
- # Find the associated media record for the image
254
- filename = File.basename(headers['location'])
255
- m = CabooseRets::Media.where(:mls_acct => p.mls_acct, :file_name => filename).first
256
-
257
- if m.nil?
258
- self.log("Can't find media record for #{p.mls_acct} #{filename}.")
259
- else
260
- m.image = URI.parse(headers['location'])
261
- media << m
262
- #m.save
263
- end
264
- end
265
-
266
- self.log("-- Uploading images to S3 for #{p.mls_acct}")
267
- media.each do |m|
268
- m.save
269
- end
270
- end
271
-
272
- def self.refresh_property_media(p)
273
- self.log("-- Deleting images and metadata for #{p.mls_acct}...")
274
- #CabooseRets::Media.where(:mls_acct => p.mls_acct, :media_type => 'Photo').destroy_all
275
- CabooseRets::Media.where(:mls_acct => p.mls_acct).destroy_all
276
-
277
- self.log("-- Downloading image metadata for #{p.mls_acct}...")
239
+
240
+ self.log("- Downloading GFX records for #{p.mls_acct}...")
278
241
  params = {
279
242
  :search_type => 'Media',
280
- :class => 'GFX',
281
- #:query => "(MLS_ACCT=*#{p.id}*),(MEDIA_TYPE=|I)",
243
+ :class => 'GFX',
282
244
  :query => "(MLS_ACCT=*#{p.id}*)",
283
245
  :timeout => -1
284
246
  }
247
+ ids = []
285
248
  self.client.search(params) do |data|
286
- m = CabooseRets::Media.new
287
- m.parse(data)
288
- #m.id = m.media_id
249
+ ids << data['MEDIA_ID']
250
+ m = CabooseRets::Media.where(:media_id => data['MEDIA_ID']).first
251
+ m = CabooseRets::Media.new if m.nil?
252
+ m.parse(data)
289
253
  m.save
290
254
  end
291
- end
292
-
293
- def self.download_agent_image(agent)
294
- self.log "Saving image for #{agent.first_name} #{agent.last_name}..."
295
- begin
296
- self.client.get_object(:resource => :Agent, :type => :Photo, :location => true, :id => agent.la_code) do |headers, content|
297
- agent.image = URI.parse(headers['location'])
298
- agent.save
299
- end
300
- rescue RETS::APIError => err
301
- self.log "No image for #{agent.first_name} #{agent.last_name}."
302
- end
303
- end
304
-
305
- def self.download_office_image(office)
306
- self.log "Saving image for #{office.lo_name}..."
307
- begin
308
- self.client.get_object(:resource => :Office, :type => :Photo, :location => true, :id => office.lo_code) do |headers, content|
309
- office.image = URI.parse(headers['location'])
310
- office.save
311
- end
312
- rescue RETS::APIError => err
313
- self.log "No image for #{office.lo_name}."
255
+
256
+ # Delete any records in the local database that shouldn't be there
257
+ puts "- Deleting GFX records for MLS ##{p.mls_acct} in the local database that are not in the remote database..."
258
+ query = "select media_id from rets_media where mls_acct = '#{p.mls_acct}'"
259
+ rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
260
+ local_ids = rows.collect{ |row| row['media_id'] }
261
+ ids_to_remove = local_ids - ids
262
+ if ids_to_remove && ids_to_remove.count > 0
263
+ query = ["delete from rets_media where media_id not in (?)", ids_to_remove]
264
+ ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
314
265
  end
266
+
315
267
  end
316
268
 
317
269
  #=============================================================================
@@ -343,6 +295,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
343
295
  end
344
296
 
345
297
  def self.coords_from_address(address)
298
+ return false
346
299
  begin
347
300
  uri = "https://maps.googleapis.com/maps/api/geocode/json?address=#{address}&sensor=false"
348
301
  uri.gsub!(" ", "+")
@@ -383,6 +336,78 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
383
336
  def self.purge_helper(class_type, date_modified)
384
337
  m = self.meta(class_type)
385
338
 
339
+ puts "Purging #{class_type}..."
340
+
341
+ # Get the total number of records
342
+ puts "- Getting total number of records for #{class_type}..."
343
+ params = {
344
+ :search_type => m.search_type,
345
+ :class => class_type,
346
+ :query => "(#{m.date_modified_field}=#{date_modified}T00:00:01+)",
347
+ :standard_names_only => true,
348
+ :timeout => -1
349
+ }
350
+ self.client.search(params.merge({ :count_mode => :only }))
351
+ count = self.client.rets_data[:code] == "20201" ? 0 : self.client.rets_data[:count]
352
+ batch_count = (count.to_f/5000.0).ceil
353
+
354
+ ids = []
355
+ k = m.remote_key_field
356
+ (0...batch_count).each do |i|
357
+ puts "- Getting ids for #{class_type} (batch #{i+1} of #{batch_count})..."
358
+ self.client.search(params.merge({ :select => [k], :limit => 5000, :offset => 5000*i })) do |data|
359
+ ids << case class_type
360
+ when 'RES' then data[k]
361
+ when 'COM' then data[k]
362
+ when 'LND' then data[k]
363
+ when 'MUL' then data[k]
364
+ when 'OFF' then data[k]
365
+ when 'AGT' then data[k]
366
+ when 'OPH' then data[k].to_i
367
+ when 'GFX' then data[k]
368
+ end
369
+ end
370
+ end
371
+
372
+ # Delete any records in the local database that shouldn't be there
373
+ puts "- Finding #{class_type} records in the local database that are not in the remote database..."
374
+ t = m.local_table
375
+ k = m.local_key_field
376
+ query = "select distinct #{k} from #{t}"
377
+ rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
378
+ local_ids = rows.collect{ |row| row[k] }
379
+ ids_to_remove = local_ids - ids
380
+ puts "- Found #{ids_to_remove.count} #{class_type} records in the local database that are not in the remote database."
381
+ puts "- Deleting #{class_type} records in the local database that shouldn't be there..."
382
+ query = ["delete from #{t} where #{k} not in (?)", ids_to_remove]
383
+ ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
384
+
385
+ # Find any ids in the remote database that should be in the local database
386
+ puts "- Finding #{class_type} records in the remote database that should be in the local database..."
387
+ query = "select distinct #{k} from #{t}"
388
+ rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
389
+ local_ids = rows.collect{ |row| row[k] }
390
+ ids_to_add = ids - local_ids
391
+ puts "- Found #{ids_to_add.count} #{class_type} records in the remote database that we need to add to the local database."
392
+ ids_to_add.each do |id|
393
+ puts "- Importing #{id}..."
394
+ case class_type
395
+ when 'RES' then self.delay.import_residential_property(id, false)
396
+ when 'COM' then self.delay.import_commercial_property(id, false)
397
+ when 'LND' then self.delay.import_land_property(id, false)
398
+ when 'MUL' then self.delay.import_multi_family_property(id, false)
399
+ when 'OFF' then self.delay.import_office(id, false)
400
+ when 'AGT' then self.delay.import_agent(id, false)
401
+ when 'OPH' then self.delay.import_open_house(id, false)
402
+ when 'GFX' then self.delay.import_media(id, false)
403
+ end
404
+ end
405
+
406
+ end
407
+
408
+ def self.get_media_urls
409
+ m = self.meta(class_type)
410
+
386
411
  # Get the total number of records
387
412
  params = {
388
413
  :search_type => m.search_type,
@@ -444,8 +469,8 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
444
469
  #=============================================================================
445
470
 
446
471
  def self.log(msg)
447
- #puts "[rets_importer] #{msg}"
448
- Rails.logger.info("[rets_importer] #{msg}")
472
+ puts "[rets_importer] #{msg}"
473
+ #Rails.logger.info("[rets_importer] #{msg}")
449
474
  end
450
475
 
451
476
  #=============================================================================
@@ -458,6 +483,9 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
458
483
 
459
484
  begin
460
485
  overlap = 30.seconds
486
+ puts DateTime.now
487
+ puts self.last_purged
488
+ puts (DateTime.now - self.last_purged)
461
489
  if (DateTime.now - self.last_purged).to_i > 1
462
490
  self.purge
463
491
  self.save_last_purged(task_started)
@@ -0,0 +1,621 @@
1
+ ##require 'ruby-rets'
2
+ #require "rets/version"
3
+ #require "rets/exceptions"
4
+ #require "rets/client"
5
+ #require "rets/http"
6
+ #require "rets/stream_http"
7
+ #require "rets/base/core"
8
+ #require "rets/base/sax_search"
9
+ #require "rets/base/sax_metadata"
10
+ #
11
+ #require 'httparty'
12
+ #require 'json'
13
+ #
14
+ ## http://rets.solidearth.com/ClientHome.aspx
15
+ #
16
+ #class CabooseRets::RetsImporter # < ActiveRecord::Base
17
+ #
18
+ # @@rets_client = nil
19
+ # @@config = nil
20
+ #
21
+ # def self.config
22
+ # return @@config
23
+ # end
24
+ #
25
+ # def self.get_config
26
+ # @@config = {
27
+ # 'url' => nil, # URL to the RETS login
28
+ # 'username' => nil,
29
+ # 'password' => nil,
30
+ # 'temp_path' => nil,
31
+ # 'log_file' => nil,
32
+ # 'media_base_url' => nil
33
+ # }
34
+ # config = YAML::load(File.open("#{Rails.root}/config/rets_importer.yml"))
35
+ # config = config[Rails.env]
36
+ # config.each { |key,val| @@config[key] = val }
37
+ # end
38
+ #
39
+ # def self.client
40
+ # self.get_config if @@config.nil? || @@config['url'].nil?
41
+ #
42
+ # if @@rets_client.nil?
43
+ # @@rets_client = RETS::Client.login(
44
+ # :url => @@config['url'],
45
+ # :username => @@config['username'],
46
+ # :password => @@config['password']
47
+ # )
48
+ # end
49
+ # return @@rets_client
50
+ # end
51
+ #
52
+ # def self.meta(class_type)
53
+ # case class_type
54
+ # when 'RES' then Caboose::StdClass.new({ :search_type => 'Property' , :remote_key_field => 'MLS_ACCT' , :local_key_field => 'mls_acct' , :local_table => 'rets_residential' , :date_modified_field => 'DATE_MODIFIED' })
55
+ # when 'COM' then Caboose::StdClass.new({ :search_type => 'Property' , :remote_key_field => 'MLS_ACCT' , :local_key_field => 'mls_acct' , :local_table => 'rets_commercial' , :date_modified_field => 'DATE_MODIFIED' })
56
+ # when 'LND' then Caboose::StdClass.new({ :search_type => 'Property' , :remote_key_field => 'MLS_ACCT' , :local_key_field => 'mls_acct' , :local_table => 'rets_land' , :date_modified_field => 'DATE_MODIFIED' })
57
+ # when 'MUL' then Caboose::StdClass.new({ :search_type => 'Property' , :remote_key_field => 'MLS_ACCT' , :local_key_field => 'mls_acct' , :local_table => 'rets_multi_family' , :date_modified_field => 'DATE_MODIFIED' })
58
+ # when 'OFF' then Caboose::StdClass.new({ :search_type => 'Office' , :remote_key_field => 'LO_LO_CODE' , :local_key_field => 'lo_code' , :local_table => 'rets_offices' , :date_modified_field => 'LO_DATE_MODIFIED' })
59
+ # when 'AGT' then Caboose::StdClass.new({ :search_type => 'Agent' , :remote_key_field => 'LA_LA_CODE' , :local_key_field => 'la_code' , :local_table => 'rets_agents' , :date_modified_field => 'LA_DATE_MODIFIED' })
60
+ # when 'OPH' then Caboose::StdClass.new({ :search_type => 'OpenHouse' , :remote_key_field => 'ID' , :local_key_field => 'id' , :local_table => 'rets_open_houses' , :date_modified_field => 'DATE_MODIFIED' })
61
+ # when 'GFX' then Caboose::StdClass.new({ :search_type => 'Media' , :remote_key_field => 'MEDIA_ID' , :local_key_field => 'media_id' , :local_table => 'rets_media' , :date_modified_field => 'DATE_MODIFIED' })
62
+ # end
63
+ # end
64
+ #
65
+ # #=============================================================================
66
+ # # Import method
67
+ # #=============================================================================
68
+ #
69
+ # def self.import(class_type, query)
70
+ # m = self.meta(class_type)
71
+ # self.log("Importing #{m.search_type}:#{class_type} with query #{query}...")
72
+ # self.get_config if @@config.nil? || @@config['url'].nil?
73
+ # params = {
74
+ # :search_type => m.search_type,
75
+ # :class => class_type,
76
+ # :query => query,
77
+ # :limit => -1,
78
+ # :timeout => -1
79
+ # }
80
+ # obj = nil
81
+ # begin
82
+ # self.client.search(params) do |data|
83
+ # obj = self.get_instance_with_id(class_type, data)
84
+ # if obj.nil?
85
+ # self.log("Error: object is nil")
86
+ # self.log(data.inspect)
87
+ # next
88
+ # end
89
+ # obj.parse(data)
90
+ # obj.save
91
+ # end
92
+ # rescue RETS::HTTPError => err
93
+ # self.log "Import error for #{class_type}: #{query}"
94
+ # self.log err.message
95
+ # end
96
+ #
97
+ # end
98
+ #
99
+ # def self.get_instance_with_id(class_type, data)
100
+ # obj = nil
101
+ # m = case class_type
102
+ # when 'OPH' then CabooseRets::OpenHouse
103
+ # when 'GFX' then CabooseRets::Media
104
+ # when 'COM' then CabooseRets::CommercialProperty
105
+ # when 'LND' then CabooseRets::LandProperty
106
+ # when 'MUL' then CabooseRets::MultiFamilyProperty
107
+ # when 'RES' then CabooseRets::ResidentialProperty
108
+ # when 'AGT' then CabooseRets::Agent
109
+ # when 'OFF' then CabooseRets::Office
110
+ # end
111
+ # obj = case class_type
112
+ # when 'OPH' then m.where(:id => data['ID'].to_i ).exists? ? m.where(:id => data['ID'].to_i ).first : m.new(:id => data['ID'].to_i )
113
+ # when 'GFX' then m.where(:media_id => data['MEDIA_ID'] ).exists? ? m.where(:media_id => data['MEDIA_ID'] ).first : m.new(:media_id => data['MEDIA_ID'] )
114
+ # when 'COM' then m.where(:id => data['MLS_ACCT'].to_i ).exists? ? m.where(:id => data['MLS_ACCT'].to_i ).first : m.new(:id => data['MLS_ACCT'].to_i )
115
+ # when 'LND' then m.where(:id => data['MLS_ACCT'].to_i ).exists? ? m.where(:id => data['MLS_ACCT'].to_i ).first : m.new(:id => data['MLS_ACCT'].to_i )
116
+ # when 'MUL' then m.where(:id => data['MLS_ACCT'].to_i ).exists? ? m.where(:id => data['MLS_ACCT'].to_i ).first : m.new(:id => data['MLS_ACCT'].to_i )
117
+ # when 'RES' then m.where(:id => data['MLS_ACCT'].to_i ).exists? ? m.where(:id => data['MLS_ACCT'].to_i ).first : m.new(:id => data['MLS_ACCT'].to_i )
118
+ # when 'AGT' then m.where(:la_code => data['LA_LA_CODE'] ).exists? ? m.where(:la_code => data['LA_LA_CODE'] ).first : m.new(:la_code => data['LA_LA_CODE'] )
119
+ # when 'OFF' then m.where(:lo_code => data['LO_LO_CODE'] ).exists? ? m.where(:lo_code => data['LO_LO_CODE'] ).first : m.new(:lo_code => data['LO_LO_CODE'] )
120
+ # end
121
+ # return obj
122
+ # end
123
+ #
124
+ # #=============================================================================
125
+ # # Main updater
126
+ # #=============================================================================
127
+ #
128
+ # def self.update_after(date_modified, save_images = true)
129
+ # self.update_helper('RES', date_modified, save_images)
130
+ # self.update_helper('COM', date_modified, save_images)
131
+ # self.update_helper('LND', date_modified, save_images)
132
+ # self.update_helper('MUL', date_modified, save_images)
133
+ # self.update_helper('OFF', date_modified, save_images)
134
+ # self.update_helper('AGT', date_modified, save_images)
135
+ # self.update_helper('OPH', date_modified, save_images)
136
+ # end
137
+ #
138
+ # def self.update_helper(class_type, date_modified, save_images = true)
139
+ # m = self.meta(class_type)
140
+ # k = m.remote_key_field
141
+ # params = {
142
+ # :search_type => m.search_type,
143
+ # :class => class_type,
144
+ # :select => [m.remote_key_field],
145
+ # :query => "(#{m.date_modified_field}=#{date_modified.strftime("%FT%T")}+)",
146
+ # :standard_names_only => true,
147
+ # :timeout => -1
148
+ # }
149
+ # self.client.search(params) do |data|
150
+ # case class_type
151
+ # when 'RES' then self.delay(:priority => 10).import_residential_property( data[k], save_images)
152
+ # when 'COM' then self.delay(:priority => 10).import_commercial_property( data[k], save_images)
153
+ # when 'LND' then self.delay(:priority => 10).import_land_property( data[k], save_images)
154
+ # when 'MUL' then self.delay(:priority => 10).import_multi_family_property( data[k], save_images)
155
+ # when 'OFF' then self.delay(:priority => 10).import_office( data[k], save_images)
156
+ # when 'AGT' then self.delay(:priority => 10).import_agent( data[k], save_images)
157
+ # when 'OPH' then self.delay(:priority => 10).import_open_house( data[k], save_images)
158
+ # end
159
+ # end
160
+ # end
161
+ #
162
+ # #=============================================================================
163
+ # # Single model import methods (called from a worker dyno)
164
+ # #=============================================================================
165
+ #
166
+ # def self.import_property(mls_acct, save_images = true)
167
+ # self.import('RES', "(MLS_ACCT=*#{mls_acct}*)")
168
+ # p = CabooseRets::ResidentialProperty.where(:id => mls_acct.to_i).first
169
+ # if p.nil?
170
+ # self.import('COM', "(MLS_ACCT=*#{mls_acct}*)")
171
+ # p = CabooseRets::CommercialProperty.where(:id => mls_acct.to_i).first
172
+ # if p.nil?
173
+ # self.import('LND', "(MLS_ACCT=*#{mls_acct}*)")
174
+ # p = CabooseRets::LandProperty.where(:id => mls_acct.to_i).first
175
+ # if p.nil?
176
+ # self.import('MUL', "(MLS_ACCT=*#{mls_acct}*)")
177
+ # p = CabooseRets::MultiFamilyProperty.where(:id => mls_acct.to_i).first
178
+ # return if p.nil?
179
+ # end
180
+ # end
181
+ # end
182
+ # self.download_property_images(p, save_images)
183
+ # end
184
+ #
185
+ # def self.import_residential_property(mls_acct, save_images = true)
186
+ # self.import('RES', "(MLS_ACCT=*#{mls_acct}*)")
187
+ # p = CabooseRets::ResidentialProperty.where(:id => mls_acct.to_i).first
188
+ # self.download_property_images(p, save_images)
189
+ # self.update_coords(p)
190
+ # end
191
+ #
192
+ # def self.import_commercial_property(mls_acct, save_images = true)
193
+ # self.import('COM', "(MLS_ACCT=*#{mls_acct}*)")
194
+ # p = CabooseRets::CommercialProperty.where(:id => mls_acct.to_i).first
195
+ # self.download_property_images(p, save_images)
196
+ # self.update_coords(p)
197
+ # end
198
+ #
199
+ # def self.import_land_property(mls_acct, save_images = true)
200
+ # self.import('LND', "(MLS_ACCT=*#{mls_acct}*)")
201
+ # p = CabooseRets::LandProperty.where(:id => mls_acct.to_i).first
202
+ # self.download_property_images(p, save_images)
203
+ # self.update_coords(p)
204
+ # end
205
+ #
206
+ # def self.import_multi_family_property(mls_acct, save_images = true)
207
+ # self.import('MUL', "(MLS_ACCT=*#{mls_acct}*)")
208
+ # p = CabooseRets::MultiFamilyProperty.where(:id => mls_acct.to_i).first
209
+ # self.download_property_images(p, save_images)
210
+ # self.update_coords(p)
211
+ # end
212
+ #
213
+ # def self.import_office(lo_code, save_images = true)
214
+ # self.import('OFF', "(LO_LO_CODE=*#{lo_code}*)")
215
+ # office = CabooseRets::Office.where(:lo_code => lo_code.to_s).first
216
+ # self.download_office_image(office) if save_images == true
217
+ # end
218
+ #
219
+ # def self.import_agent(la_code, save_images = true)
220
+ # self.import('AGT', "(LA_LA_CODE=*#{la_code}*)")
221
+ # a = CabooseRets::Agent.where(:la_code => la_code.to_s).first
222
+ # self.download_agent_image(a) if save_images == true
223
+ # end
224
+ #
225
+ # def self.import_open_house(id, save_images = true)
226
+ # self.import('OPH', "((ID=#{id}+),(ID=#{id}-))")
227
+ # end
228
+ #
229
+ # def self.import_media(id, save_images = true)
230
+ # self.import('GFX', "((MEDIA_ID=#{id}+),(MEDIA_ID=#{id}-))")
231
+ # #m = CabooseRets::Media.where(:media_id => id.to_s).first
232
+ # #if m.nil?
233
+ # # self.log("Can't find media record for #{id}.")
234
+ # # return
235
+ # #end
236
+ # #self.client.get_object(:resource => :Property, :type => :Photo, :location => true, :id => m.mls_acct) do |headers, content|
237
+ # # if headers['object-id'].to_i == m.media_order
238
+ # # m.url = headers['location']
239
+ # # #m.image = URI.parse(headers['location'])
240
+ # # end
241
+ # #end
242
+ # #m.save
243
+ # end
244
+ #
245
+ # #=============================================================================
246
+ # # Images
247
+ # #=============================================================================
248
+ #
249
+ # def self.download_property_images(p, save_images = true)
250
+ # return if save_images == false
251
+ # self.refresh_property_media(p)
252
+ #
253
+ # #self.log("-- Downloading images and resizing for #{p.mls_acct}")
254
+ # #media = []
255
+ # #self.client.get_object(:resource => :Property, :type => :Photo, :location => true, :id => p.id) do |headers, content|
256
+ # #
257
+ # # # Find the associated media record for the image
258
+ # # #filename = File.basename(headers['location'])
259
+ # # #m = CabooseRets::Media.where(:mls_acct => p.mls_acct, :file_name => filename).first
260
+ # # m = CabooseRets::Media.where(:mls_acct => p.mls_acct, :media_order => headers['object-id'].to_i).first
261
+ # #
262
+ # # if m.nil?
263
+ # # self.log("Can't find media record for #{p.mls_acct} #{filename}.")
264
+ # # else
265
+ # # m.url = headers['location']
266
+ # # #m.image = URI.parse(headers['location'])
267
+ # # media << m
268
+ # # #m.save
269
+ # # end
270
+ # #end
271
+ # #
272
+ # #self.log("-- Uploading images to S3 for #{p.mls_acct}")
273
+ # #media.each do |m|
274
+ # # m.save
275
+ # #end
276
+ # end
277
+ #
278
+ # def self.refresh_property_media(p)
279
+ # #self.log("-- Deleting images and metadata for #{p.mls_acct}...")
280
+ # #CabooseRets::Media.where(:mls_acct => p.mls_acct, :media_type => 'Photo').destroy_all
281
+ # #CabooseRets::Media.where(:mls_acct => p.mls_acct).destroy_all
282
+ #
283
+ # self.log("-- Downloading GFX records for #{p.mls_acct}...")
284
+ # params = {
285
+ # :search_type => 'Media',
286
+ # :class => 'GFX',
287
+ # :query => "(MLS_ACCT=*#{p.id}*)",
288
+ # :timeout => -1
289
+ # }
290
+ # ids = []
291
+ # self.client.search(params) do |data|
292
+ # ids << data['MEDIA_ID']
293
+ # m = CabooseRets::Media.new
294
+ # m.parse(data)
295
+ # m.save
296
+ # end
297
+ #
298
+ # # Delete any records in the local database that shouldn't be there
299
+ # puts "- Finding GFX records for MLS ##{p.mls_acct} in the local database that are not in the remote database..."
300
+ # query = "select media_id from rets_media where mls_acct = '#{p.mls_acct}'"
301
+ # rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
302
+ # local_ids = rows.collect{ |row| row[k] }
303
+ # ids_to_remove = local_ids - ids
304
+ # if ids_to_remove && ids_to_remove > 0
305
+ # query = ["delete from rets_media where media_id not in (?)", ids_to_remove]
306
+ # ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
307
+ # end
308
+ #
309
+ # end
310
+ #
311
+ # #def self.download_agent_image(agent)
312
+ # # self.log "Saving image for #{agent.first_name} #{agent.last_name}..."
313
+ # # begin
314
+ # # self.client.get_object(:resource => :Agent, :type => :Photo, :location => true, :id => agent.la_code) do |headers, content|
315
+ # # puts headers.inspect
316
+ # # agent.image = URI.parse(headers['location'])
317
+ # # agent.save
318
+ # # end
319
+ # # rescue RETS::APIError => err
320
+ # # self.log "No image for #{agent.first_name} #{agent.last_name}."
321
+ # # end
322
+ # #end
323
+ #
324
+ # #def self.download_office_image(office)
325
+ # # self.log "Saving image for #{office.lo_name}..."
326
+ # # begin
327
+ # # self.client.get_object(:resource => :Office, :type => :Photo, :location => true, :id => office.lo_code) do |headers, content|
328
+ # # office.image = URI.parse(headers['location'])
329
+ # # office.save
330
+ # # end
331
+ # # rescue RETS::APIError => err
332
+ # # self.log "No image for #{office.lo_name}."
333
+ # # end
334
+ # #end
335
+ #
336
+ # #=============================================================================
337
+ # # GPS
338
+ # #=============================================================================
339
+ #
340
+ # def self.update_coords(p = nil)
341
+ # if p.nil?
342
+ # models = [CabooseRets::CommercialProperty, CabooseRets::LandProperty, CabooseRets::MultiFamilyProperty, CabooseRets::ResidentialProperty]
343
+ # names = ["commercial", "land", "multi-family", "residential"]
344
+ # i = 0
345
+ # models.each do |model|
346
+ # self.log "Updating coords #{names[i]} properties..."
347
+ # model.where(:latitude => nil).reorder(:mls_acct).each do |p|
348
+ # self.update_coords(p)
349
+ # end
350
+ # i = i + 1
351
+ # end
352
+ # return
353
+ # end
354
+ #
355
+ # self.log "Getting coords for mls_acct #{p.mls_acct}..."
356
+ # coords = self.coords_from_address(CGI::escape "#{p.street_num} #{p.street_name}, #{p.city}, #{p.state} #{p.zip}")
357
+ # return if coords.nil? || coords == false
358
+ #
359
+ # p.latitude = coords['lat']
360
+ # p.longitude = coords['lng']
361
+ # p.save
362
+ # end
363
+ #
364
+ # def self.coords_from_address(address)
365
+ # return false
366
+ # begin
367
+ # uri = "https://maps.googleapis.com/maps/api/geocode/json?address=#{address}&sensor=false"
368
+ # uri.gsub!(" ", "+")
369
+ # resp = HTTParty.get(uri)
370
+ # json = JSON.parse(resp.body)
371
+ # return json['results'][0]['geometry']['location']
372
+ # rescue
373
+ # self.log "Error: #{uri}"
374
+ # sleep(2)
375
+ # return false
376
+ # end
377
+ # end
378
+ #
379
+ # #=============================================================================
380
+ # # Purging
381
+ # #=============================================================================
382
+ #
383
+ # def self.purge
384
+ # self.purge_residential
385
+ # self.purge_commercial
386
+ # self.purge_land
387
+ # self.purge_multi_family
388
+ # self.purge_offices
389
+ # self.purge_agents
390
+ # self.purge_open_houses
391
+ # self.purge_media
392
+ # end
393
+ #
394
+ # def self.purge_residential() self.purge_helper('RES', '2012-01-01') end
395
+ # def self.purge_commercial() self.purge_helper('COM', '2012-01-01') end
396
+ # def self.purge_land() self.purge_helper('LND', '2012-01-01') end
397
+ # def self.purge_multi_family() self.purge_helper('MUL', '2012-01-01') end
398
+ # def self.purge_offices() self.purge_helper('OFF', '2012-01-01') end
399
+ # def self.purge_agents() self.purge_helper('AGT', '2012-01-01') end
400
+ # def self.purge_open_houses() self.purge_helper('OPH', '2012-01-01') end
401
+ # def self.purge_media() self.purge_helper('GFX', '2012-01-01') end
402
+ #
403
+ # def self.purge_helper(class_type, date_modified)
404
+ # m = self.meta(class_type)
405
+ #
406
+ # puts "Purging #{class_type}..."
407
+ #
408
+ # # Get the total number of records
409
+ # puts "- Getting total number of records for #{class_type}..."
410
+ # params = {
411
+ # :search_type => m.search_type,
412
+ # :class => class_type,
413
+ # :query => "(#{m.date_modified_field}=#{date_modified}T00:00:01+)",
414
+ # :standard_names_only => true,
415
+ # :timeout => -1
416
+ # }
417
+ # self.client.search(params.merge({ :count_mode => :only }))
418
+ # count = self.client.rets_data[:code] == "20201" ? 0 : self.client.rets_data[:count]
419
+ # batch_count = (count.to_f/5000.0).ceil
420
+ #
421
+ # ids = []
422
+ # k = m.remote_key_field
423
+ # (0...batch_count).each do |i|
424
+ # puts "- Getting ids for #{class_type} (batch #{i+1} of #{batch_count})..."
425
+ # self.client.search(params.merge({ :select => [k], :limit => 5000, :offset => 5000*i })) do |data|
426
+ # ids << case class_type
427
+ # when 'RES' then data[k]
428
+ # when 'COM' then data[k]
429
+ # when 'LND' then data[k]
430
+ # when 'MUL' then data[k]
431
+ # when 'OFF' then data[k]
432
+ # when 'AGT' then data[k]
433
+ # when 'OPH' then data[k].to_i
434
+ # when 'GFX' then data[k]
435
+ # end
436
+ # end
437
+ # end
438
+ #
439
+ # # Delete any records in the local database that shouldn't be there
440
+ # puts "- Finding #{class_type} records in the local database that are not in the remote database..."
441
+ # t = m.local_table
442
+ # k = m.local_key_field
443
+ # query = "select distinct #{k} from #{t}"
444
+ # rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
445
+ # local_ids = rows.collect{ |row| row[k] }
446
+ # ids_to_remove = local_ids - ids
447
+ # puts "- Found #{ids_to_remove.count} #{class_type} records in the local database that are not in the remote database."
448
+ # puts "- Deleting #{class_type} records in the local database that shouldn't be there..."
449
+ # query = ["delete from #{t} where #{k} not in (?)", ids_to_remove]
450
+ # ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
451
+ #
452
+ # # Find any ids in the remote database that should be in the local database
453
+ # puts "- Finding #{class_type} records in the remote database that should be in the local database..."
454
+ # query = "select distinct #{k} from #{t}"
455
+ # rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
456
+ # local_ids = rows.collect{ |row| row[k] }
457
+ # ids_to_add = ids - local_ids
458
+ # puts "- Found #{ids_to_add.count} #{class_type} records in the remote database that we need to add to the local database."
459
+ # ids_to_add.each do |id|
460
+ # puts "- Importing #{id}..."
461
+ # case class_type
462
+ # when 'RES' then self.delay.import_residential_property(id, false)
463
+ # when 'COM' then self.delay.import_commercial_property(id, false)
464
+ # when 'LND' then self.delay.import_land_property(id, false)
465
+ # when 'MUL' then self.delay.import_multi_family_property(id, false)
466
+ # when 'OFF' then self.delay.import_office(id, false)
467
+ # when 'AGT' then self.delay.import_agent(id, false)
468
+ # when 'OPH' then self.delay.import_open_house(id, false)
469
+ # when 'GFX' then self.delay.import_media(id, false)
470
+ # end
471
+ # end
472
+ #
473
+ # end
474
+ #
475
+ # def self.get_media_urls
476
+ # m = self.meta(class_type)
477
+ #
478
+ # # Get the total number of records
479
+ # params = {
480
+ # :search_type => m.search_type,
481
+ # :class => class_type,
482
+ # :query => "(#{m.date_modified_field}=#{date_modified}T00:00:01+)",
483
+ # :standard_names_only => true,
484
+ # :timeout => -1
485
+ # }
486
+ # self.client.search(params.merge({ :count_mode => :only }))
487
+ # count = self.client.rets_data[:code] == "20201" ? 0 : self.client.rets_data[:count]
488
+ # batch_count = (count.to_f/5000.0).ceil
489
+ #
490
+ # ids = []
491
+ # k = m.remote_key_field
492
+ # (0...batch_count).each do |i|
493
+ # self.client.search(params.merge({ :select => [k], :limit => 5000, :offset => 5000*i })) do |data|
494
+ # ids << case class_type
495
+ # when 'RES' then data[k]
496
+ # when 'COM' then data[k]
497
+ # when 'LND' then data[k]
498
+ # when 'MUL' then data[k]
499
+ # when 'OFF' then data[k]
500
+ # when 'AGT' then data[k]
501
+ # when 'OPH' then data[k].to_i
502
+ # when 'GFX' then data[k]
503
+ # end
504
+ # end
505
+ # end
506
+ #
507
+ # # Delete any records in the local database that shouldn't be there
508
+ # t = m.local_table
509
+ # k = m.local_key_field
510
+ # query = ["delete from #{t} where #{k} not in (?)", ids]
511
+ # ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
512
+ #
513
+ # # Find any ids in the remote database that should be in the local database
514
+ # query = "select distinct #{k} from #{t}"
515
+ # rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
516
+ # local_ids = rows.collect{ |row| row[k] }
517
+ # ids_to_add = ids - local_ids
518
+ # ids_to_add.each do |id|
519
+ # puts "Importing #{id}..."
520
+ # case class_type
521
+ # when 'RES' then self.delay.import_residential_property(id, false)
522
+ # when 'COM' then self.delay.import_commercial_property(id, false)
523
+ # when 'LND' then self.delay.import_land_property(id, false)
524
+ # when 'MUL' then self.delay.import_multi_family_property(id, false)
525
+ # when 'OFF' then self.delay.import_office(id, false)
526
+ # when 'AGT' then self.delay.import_agent(id, false)
527
+ # when 'OPH' then self.delay.import_open_house(id, false)
528
+ # when 'GFX' then self.delay.import_media(id)
529
+ # end
530
+ # end
531
+ #
532
+ # end
533
+ #
534
+ # #=============================================================================
535
+ # # Logging
536
+ # #=============================================================================
537
+ #
538
+ # def self.log(msg)
539
+ # puts "[rets_importer] #{msg}"
540
+ # #Rails.logger.info("[rets_importer] #{msg}")
541
+ # end
542
+ #
543
+ # #=============================================================================
544
+ # # Locking update task
545
+ # #=============================================================================
546
+ #
547
+ # def self.update_rets
548
+ # return if self.task_is_locked
549
+ # task_started = self.lock_task
550
+ #
551
+ # begin
552
+ # overlap = 30.seconds
553
+ # puts DateTime.now
554
+ # puts self.last_purged
555
+ # puts (DateTime.now - self.last_purged)
556
+ # if (DateTime.now - self.last_purged).to_i > 1
557
+ # self.purge
558
+ # self.save_last_purged(task_started)
559
+ # #overlap = 1.month
560
+ # end
561
+ # self.update_after(self.last_updated - overlap)
562
+ # self.save_last_updated(task_started)
563
+ # self.unlock_task
564
+ # rescue
565
+ # raise
566
+ # ensure
567
+ # self.unlock_task_if_last_updated(task_started)
568
+ # end
569
+ #
570
+ # # Start the same update process in five minutes
571
+ # self.delay(:run_at => 1.minutes.from_now).update_rets
572
+ # end
573
+ #
574
+ # def self.last_updated
575
+ # if !Caboose::Setting.exists?(:name => 'rets_last_updated')
576
+ # Caboose::Setting.create(:name => 'rets_last_updated', :value => '2013-08-06T00:00:01')
577
+ # end
578
+ # s = Caboose::Setting.where(:name => 'rets_last_updated').first
579
+ # return DateTime.parse(s.value)
580
+ # end
581
+ #
582
+ # def self.last_purged
583
+ # if !Caboose::Setting.exists?(:name => 'rets_last_purged')
584
+ # Caboose::Setting.create(:name => 'rets_last_purged', :value => '2013-08-06T00:00:01')
585
+ # end
586
+ # s = Caboose::Setting.where(:name => 'rets_last_purged').first
587
+ # return DateTime.parse(s.value)
588
+ # end
589
+ #
590
+ # def self.save_last_updated(d)
591
+ # s = Caboose::Setting.where(:name => 'rets_last_updated').first
592
+ # s.value = d.strftime('%FT%T')
593
+ # s.save
594
+ # end
595
+ #
596
+ # def self.save_last_purged(d)
597
+ # s = Caboose::Setting.where(:name => 'rets_last_purged').first
598
+ # s.value = d.strftime('%FT%T')
599
+ # s.save
600
+ # end
601
+ #
602
+ # def self.task_is_locked
603
+ # return Caboose::Setting.exists?(:name => 'rets_update_running')
604
+ # end
605
+ #
606
+ # def self.lock_task
607
+ # d = DateTime.now.utc - 5.hours
608
+ # Caboose::Setting.create(:name => 'rets_update_running', :value => d.strftime('%F %T'))
609
+ # return d
610
+ # end
611
+ #
612
+ # def self.unlock_task
613
+ # Caboose::Setting.where(:name => 'rets_update_running').first.destroy
614
+ # end
615
+ #
616
+ # def self.unlock_task_if_last_updated(d)
617
+ # setting = Caboose::Setting.where(:name => 'rets_update_running').first
618
+ # self.unlock_task if setting && d.strftime('%F %T') == setting.value
619
+ # end
620
+ #
621
+ #end
@@ -9,6 +9,12 @@ class CabooseRets::Schema < Caboose::Utilities::Schema
9
9
  }
10
10
  end
11
11
 
12
+ def self.indexes
13
+ {
14
+ CabooseRets::Media => [:media_id]
15
+ }
16
+ end
17
+
12
18
  # The schema of the database
13
19
  # { Model => [[name, data_type, options]] }
14
20
  def self.schema
@@ -377,10 +383,10 @@ class CabooseRets::Schema < Caboose::Utilities::Schema
377
383
  [ :file_name , :string ],
378
384
  [ :media_id , :string ],
379
385
  [ :media_order , :integer, { :default => 0 }],
380
- [ :media_remarks , :text ],
386
+ [ :media_remarks , :text ],
381
387
  [ :media_type , :string ],
382
388
  [ :mls_acct , :string ],
383
- [ :url , :text ]
389
+ [ :url , :text ]
384
390
  ],
385
391
  CabooseRets::MultiFamilyProperty => [
386
392
  [ :acreage , :text ],
@@ -9,7 +9,7 @@
9
9
  <% @properties.each do |p| %>
10
10
  <li>
11
11
  <% if p.images && p.images.count > 0 %>
12
- <div class='image'><a href="/residential/<%= p.mls_acct %>/details"><img src="<%= p.images[0].url(:thumb) %>" /></a></div>
12
+ <div class='image'><a href="/residential/<%= p.mls_acct %>/details"><img src="<%= p.images[0].image_url(:thumb) %>" /></a></div>
13
13
  <% end %>
14
14
  <div class="address"><% if !p.unit_num.nil? && p.unit_num.strip.length > 0 %>Unit <%= p.unit_num %>, <% end %><%= p.street_num %> <%= p.street_name.titleize %></div>
15
15
  <% if p.agent %>
data/lib/caboose-rets.rb CHANGED
@@ -4,5 +4,17 @@ module CabooseRets
4
4
 
5
5
  mattr_accessor :default_property_sort
6
6
  @@default_property_sort = 'current_price DESC, mls_acct'
7
-
7
+
8
+ mattr_accessor :use_hosted_images
9
+ @@use_hosted_images = true
10
+
11
+ mattr_accessor :media_base_url
12
+ @@media_base_url = ''
13
+
14
+ mattr_accessor :agents_base_url
15
+ @@agents_base_url = ''
16
+
17
+ mattr_accessor :offices_base_url
18
+ @@offices_base_url = ''
19
+
8
20
  end
@@ -1,3 +1,3 @@
1
1
  module CabooseRets
2
- VERSION = '0.0.69'
2
+ VERSION = '0.0.70'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: caboose-rets
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.69
4
+ version: 0.0.70
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Barry
@@ -58,6 +58,7 @@ files:
58
58
  - app/models/caboose_rets/open_house.rb
59
59
  - app/models/caboose_rets/residential_property.rb
60
60
  - app/models/caboose_rets/rets_importer.rb
61
+ - app/models/caboose_rets/rets_importer_bak.rb
61
62
  - app/models/caboose_rets/rets_plugin.rb
62
63
  - app/models/caboose_rets/saved_property.rb
63
64
  - app/models/caboose_rets/saved_search.rb