caboose-rets 0.1.73 → 0.1.74
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/caboose_rets/log.rb +6 -0
- data/app/models/caboose_rets/rets_importer.rb +55 -41
- data/app/models/caboose_rets/schema.rb +7 -1
- data/lib/caboose_rets/version.rb +1 -1
- data/lib/tasks/caboose_rets.rake +64 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f2dddec676cb5213e2d840183472f60a617f5aeaa0c1c79a81a046adaf83839a
|
4
|
+
data.tar.gz: 7170eeb154afa3d3e8ea529350e054b13d0daaf97cedec4e27e2031ea3bfd360
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6dc6e4147c90ac16557f6d9d4adc4d32b41c3496d3109cd5f992858c8c68cfbf5511369c2d0cacdf69e6829acfb9ae46f5161499d3d8b9d00ca385265a96ead0
|
7
|
+
data.tar.gz: 79ba0e3691f6e0e8274b432ca6ea71fa5c4db697b3ecf6e17c88cb2dab13ff13695326f3a2c9ded9c1ab2661dcad8cfbfed815d79d339821ba9e63e478addd91
|
@@ -64,7 +64,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
64
64
|
|
65
65
|
def self.import(class_type, query)
|
66
66
|
m = self.meta(class_type)
|
67
|
-
self.
|
67
|
+
self.log3(class_type,nil,"Importing #{m.search_type}:#{class_type} with query #{query}...")
|
68
68
|
self.get_config if @@config.nil? || @@config['url'].nil?
|
69
69
|
params = {
|
70
70
|
:search_type => m.search_type,
|
@@ -79,16 +79,16 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
79
79
|
self.client.search(params) do |data|
|
80
80
|
obj = self.get_instance_with_id(class_type, data)
|
81
81
|
if obj.nil?
|
82
|
-
self.
|
83
|
-
self.
|
82
|
+
self.log3(class_type,nil,"Error: object is nil")
|
83
|
+
self.log3(class_type,nil,data.inspect)
|
84
84
|
next
|
85
85
|
end
|
86
86
|
obj.parse(data)
|
87
87
|
obj.save
|
88
88
|
end
|
89
89
|
rescue RETS::HTTPError => err
|
90
|
-
self.
|
91
|
-
self.
|
90
|
+
self.log3(class_type,nil,"Import error for #{class_type}: #{query}")
|
91
|
+
self.log3(class_type,nil,err.message)
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
@@ -118,16 +118,17 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
118
118
|
#=============================================================================
|
119
119
|
|
120
120
|
def self.update_after(date_modified, save_images = true)
|
121
|
-
|
122
|
-
self.
|
121
|
+
si = save_images ? 'saving images' : 'not saving images'
|
122
|
+
self.log3(nil,nil,"Updating after #{date_modified} and #{si}")
|
123
|
+
self.delay(:priority => 10, :queue => 'rets').update_helper('Property' , date_modified, save_images)
|
123
124
|
self.delay(:priority => 10, :queue => 'rets').update_helper('Office' , date_modified, false)
|
124
|
-
self.delay(:priority => 10, :queue => 'rets').update_helper('Member'
|
125
|
+
self.delay(:priority => 10, :queue => 'rets').update_helper('Member' , date_modified, false)
|
125
126
|
self.delay(:priority => 10, :queue => 'rets').update_helper('OpenHouse', date_modified, false)
|
126
127
|
end
|
127
128
|
|
128
129
|
def self.update_helper(class_type, date_modified, save_images = true)
|
129
|
-
self.
|
130
|
-
self.
|
130
|
+
#self.log3(class_type,nil,"In update helper for #{class_type}")
|
131
|
+
self.log3(class_type,nil,"Updating everything modified after #{date_modified}")
|
131
132
|
m = self.meta(class_type)
|
132
133
|
k = m.remote_key_field
|
133
134
|
d = date_modified.in_time_zone(CabooseRets::timezone).strftime("%FT%T")
|
@@ -144,9 +145,9 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
144
145
|
:standard_names_only => true,
|
145
146
|
:timeout => -1
|
146
147
|
}
|
147
|
-
self.
|
148
|
+
self.log3(class_type,nil,"Searching with params: " + params.to_s)
|
148
149
|
self.client.search(params) do |data|
|
149
|
-
self.
|
150
|
+
self.log3(class_type,nil,"Resulting data: " + data.to_s)
|
150
151
|
case class_type
|
151
152
|
when 'Property' then self.delay(:priority => 10, :queue => 'rets').import_properties(data[k], save_images)
|
152
153
|
when 'Office' then self.delay(:priority => 10, :queue => 'rets').import_office( data[k], false)
|
@@ -172,31 +173,37 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
172
173
|
# end
|
173
174
|
|
174
175
|
def self.import_properties(mls_id, save_images = true)
|
176
|
+
si = save_images ? 'saving images' : 'not saving images'
|
177
|
+
self.log3('Property',mls_id,"Importing Property #{mls_id} and #{si}...")
|
175
178
|
self.import('Property', "(ListingId=#{mls_id})")
|
176
179
|
p = CabooseRets::Property.where(:mls_number => mls_id.to_s).first
|
177
180
|
if p != nil
|
178
181
|
self.download_property_images(p) if save_images
|
179
182
|
self.update_coords(p)
|
180
183
|
else
|
181
|
-
self.
|
184
|
+
self.log3(nil,nil,"No Property associated with #{mls_id}")
|
182
185
|
end
|
183
186
|
end
|
184
187
|
|
185
188
|
def self.import_office(mls_id, save_images = true)
|
189
|
+
self.log3('Office',mls_id,"Importing Office #{mls_id}...")
|
186
190
|
self.import('Office', "(OfficeMlsId=#{mls_id})")
|
187
191
|
office = CabooseRets::Office.where(:matrix_unique_id => mls_id.to_s).first
|
188
192
|
end
|
189
193
|
|
190
194
|
def self.import_agent(mls_id, save_images = true)
|
195
|
+
self.log3('Agent',mls_id,"Importing Agent #{mls_id}...")
|
191
196
|
self.import('Member', "(MemberMlsId=#{mls_id})")
|
192
197
|
a = CabooseRets::Agent.where(:mls_id => mls_id.to_s).first
|
193
198
|
end
|
194
199
|
|
195
200
|
def self.import_open_house(oh_id, save_images = true)
|
201
|
+
self.log3('OpenHouse',oh_id,"Importing Open House #{oh_id}...")
|
196
202
|
self.import('OpenHouse', "(OpenHouseKey=#{oh_id})")
|
197
203
|
end
|
198
204
|
|
199
205
|
def self.import_media(id, save_images = true)
|
206
|
+
self.log3('Media',id,"Importing Media #{id}...")
|
200
207
|
self.import('Media', "((MediaObjectID=#{id}+),(MediaObjectID=#{id}-))")
|
201
208
|
end
|
202
209
|
|
@@ -243,7 +250,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
243
250
|
# end
|
244
251
|
|
245
252
|
def self.download_property_images(p)
|
246
|
-
self.
|
253
|
+
self.log3('Property',p.mls_number,"Downloading images for #{p.mls_number}...")
|
247
254
|
begin
|
248
255
|
# Get first image
|
249
256
|
self.client.get_object(:resource => 'Property', :type => 'Photo', :location=> false, :id => "#{p.matrix_unique_id}:0") do |headers, content|
|
@@ -296,6 +303,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
296
303
|
end
|
297
304
|
|
298
305
|
def self.download_missing_images
|
306
|
+
self.log3("Property",nil,"Downloading all missing images...")
|
299
307
|
CabooseRets::Property.where("photo_count = ? OR photo_count is null", '').all.each do |p|
|
300
308
|
self.delay(:priority => 10, :queue => 'rets').import_properties(p.mls_number, true)
|
301
309
|
end
|
@@ -337,17 +345,17 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
337
345
|
if p.nil?
|
338
346
|
model = CabooseRets::Property
|
339
347
|
i = 0
|
340
|
-
self.
|
348
|
+
self.log3('Property',nil,"Updating coords properties...")
|
341
349
|
model.where(:latitude => nil).reorder(:mls_number).each do |p1|
|
342
350
|
self.delay(:priority => 10, :queue => 'rets').update_coords(p1)
|
343
351
|
end
|
344
352
|
return
|
345
353
|
end
|
346
354
|
|
347
|
-
self.
|
355
|
+
self.log3('Property',p.mls_number,"Getting coords for MLS # #{p.mls_number}...")
|
348
356
|
coords = self.coords_from_address(CGI::escape "#{p.street_number} #{p.street_name}, #{p.city}, #{p.state_or_province} #{p.postal_code}")
|
349
357
|
if coords.nil? || coords == false
|
350
|
-
self.
|
358
|
+
self.log3('Property',nil,"Can't set coords for MLS # #{p.mls_number}...")
|
351
359
|
return
|
352
360
|
end
|
353
361
|
|
@@ -375,7 +383,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
375
383
|
#=============================================================================
|
376
384
|
|
377
385
|
def self.purge
|
378
|
-
self.
|
386
|
+
self.log3(nil,nil,'purging')
|
379
387
|
self.purge_properties
|
380
388
|
self.purge_offices
|
381
389
|
self.purge_agents
|
@@ -392,10 +400,10 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
392
400
|
m = self.meta(class_type)
|
393
401
|
self.log(m.search_type)
|
394
402
|
|
395
|
-
self.
|
403
|
+
self.log3(class_type,nil,"Purging #{class_type}...")
|
396
404
|
|
397
405
|
# Get the total number of records
|
398
|
-
self.
|
406
|
+
self.log3(class_type,nil,"Getting total number of records for #{class_type}...")
|
399
407
|
|
400
408
|
statusquery = ""
|
401
409
|
|
@@ -421,7 +429,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
421
429
|
ids = []
|
422
430
|
k = m.remote_key_field
|
423
431
|
(0...batch_count).each do |i|
|
424
|
-
self.
|
432
|
+
self.log3(class_type,nil,"Getting ids for #{class_type} (batch #{i+1} of #{batch_count})...")
|
425
433
|
self.client.search(params.merge({ :select => [k], :limit => 5000, :offset => 5000*i })) do |data|
|
426
434
|
ids << (class_type == 'OpenHouse' ? data[k].to_i : data[k])
|
427
435
|
end
|
@@ -430,33 +438,33 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
430
438
|
# Only do stuff if we got a real response from the server
|
431
439
|
if ids.count > 0
|
432
440
|
|
433
|
-
|
441
|
+
self.log3(class_type,nil,"Remote IDs found: #{ids.to_s}")
|
434
442
|
|
435
443
|
# Delete any records in the local database that shouldn't be there
|
436
|
-
self.
|
444
|
+
self.log3(class_type,nil,"Finding #{class_type} records in the local database that are not in the remote database...")
|
437
445
|
t = m.local_table
|
438
446
|
k = m.local_key_field
|
439
447
|
query = "select distinct #{k} from #{t}"
|
440
448
|
rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
441
449
|
local_ids = rows.collect{ |row| row[k] }
|
442
|
-
|
450
|
+
self.log3(class_type,nil,"Local IDs found: #{local_ids.to_s}")
|
443
451
|
ids_to_remove = local_ids - ids
|
444
|
-
self.
|
445
|
-
self.
|
452
|
+
self.log3(class_type,nil,"Found #{ids_to_remove.count} #{class_type} records in the local database that are not in the remote database.")
|
453
|
+
self.log3(class_type,nil,"Deleting #{class_type} records in the local database that shouldn't be there...")
|
446
454
|
query = ["delete from #{t} where #{k} in (?)", ids_to_remove]
|
447
455
|
ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
448
456
|
|
449
457
|
# Find any ids in the remote database that should be in the local database
|
450
|
-
self.
|
458
|
+
self.log3(class_type,nil,"- Finding #{class_type} records in the remote database that should be in the local database...")
|
451
459
|
query = "select distinct #{k} from #{t}"
|
452
460
|
rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
453
461
|
local_ids = rows.collect{ |row| row[k] }
|
454
|
-
|
462
|
+
self.log3(class_type,nil,"Local IDs found: #{local_ids.to_s}")
|
455
463
|
ids_to_add = ids - local_ids
|
456
464
|
ids_to_add = ids_to_add.sort.reverse
|
457
|
-
self.
|
465
|
+
self.log3(class_type,nil,"Found #{ids_to_add.count} #{class_type} records in the remote database that we need to add to the local database.")
|
458
466
|
ids_to_add.each do |id|
|
459
|
-
self.
|
467
|
+
self.log3(class_type,nil,"Importing #{id}...")
|
460
468
|
case class_type
|
461
469
|
when "Property" then self.delay(:priority => 10, :queue => 'rets').import_properties(id, true)
|
462
470
|
when "Office" then self.delay(:priority => 10, :queue => 'rets').import_office(id, false)
|
@@ -521,14 +529,22 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
521
529
|
|
522
530
|
def self.log(msg)
|
523
531
|
puts "[rets_importer] #{msg}"
|
524
|
-
#Rails.logger.info("[rets_importer] #{msg}")
|
525
532
|
end
|
526
533
|
|
527
534
|
def self.log2(msg)
|
528
535
|
puts "======================================================================"
|
529
536
|
puts "[rets_importer] #{msg}"
|
530
537
|
puts "======================================================================"
|
531
|
-
|
538
|
+
end
|
539
|
+
|
540
|
+
def self.log3(class_name, object_id, text)
|
541
|
+
self.log2(text)
|
542
|
+
log = CabooseRets::Log.new
|
543
|
+
log.class_name = class_name
|
544
|
+
log.object_id = object_id
|
545
|
+
log.text = text
|
546
|
+
log.timestamp = DateTime.now
|
547
|
+
log.save
|
532
548
|
end
|
533
549
|
|
534
550
|
#=============================================================================
|
@@ -536,7 +552,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
536
552
|
#=============================================================================
|
537
553
|
|
538
554
|
def self.update_rets
|
539
|
-
self.
|
555
|
+
self.log3(nil,nil,"Updating rets...")
|
540
556
|
if self.task_is_locked
|
541
557
|
self.log2("Task is locked, aborting.")
|
542
558
|
return
|
@@ -545,20 +561,16 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
545
561
|
task_started = self.lock_task
|
546
562
|
|
547
563
|
begin
|
548
|
-
overlap =
|
564
|
+
overlap = 24.hours
|
549
565
|
if (DateTime.now - self.last_purged).to_f >= 0.5
|
550
566
|
self.purge
|
551
567
|
self.save_last_purged(task_started)
|
552
|
-
|
553
|
-
#overlap = 1.month
|
568
|
+
overlap = 1.week
|
554
569
|
end
|
555
|
-
|
556
|
-
self.log2("Updating after #{self.last_updated.strftime("%FT%T%:z")}...")
|
557
570
|
self.update_after(self.last_updated - overlap)
|
558
571
|
self.download_missing_images
|
559
|
-
self.
|
572
|
+
self.log3(nil,nil,"Saving the timestamp for when we updated to #{task_started.to_s}...")
|
560
573
|
self.save_last_updated(task_started)
|
561
|
-
|
562
574
|
self.log2("Unlocking the task...")
|
563
575
|
self.unlock_task
|
564
576
|
rescue Exception => err
|
@@ -570,12 +582,14 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
570
582
|
end
|
571
583
|
|
572
584
|
# Start the same update process in 20 minutes
|
573
|
-
self.
|
585
|
+
self.log3(nil,nil,"Adding the update rets task for 20 minutes from now...")
|
574
586
|
q = "handler like '%update_rets%'"
|
575
587
|
count = Delayed::Job.where(q).count
|
576
588
|
if count == 0 || (count == 1 && Delayed::Job.where(q).first.locked_at)
|
577
589
|
self.delay(:run_at => 20.minutes.from_now, :priority => 10, :queue => 'rets').update_rets
|
578
590
|
end
|
591
|
+
# Delete old logs
|
592
|
+
CabooseRets::Log.where("timestamp < ?",(DateTime.now - 30.days)).destroy_all
|
579
593
|
end
|
580
594
|
|
581
595
|
def self.last_updated
|
@@ -290,7 +290,13 @@ class CabooseRets::Schema < Caboose::Utilities::Schema
|
|
290
290
|
[ :zoning , :text],
|
291
291
|
[ :zoning_northport , :text],
|
292
292
|
[ :zoning_tusc , :text]
|
293
|
-
],
|
293
|
+
],
|
294
|
+
CabooseRets::Log => [
|
295
|
+
[ :class_name, :string ],
|
296
|
+
[ :object_id, :string ],
|
297
|
+
[ :text, :text ],
|
298
|
+
[ :timestamp, :datetime ]
|
299
|
+
],
|
294
300
|
CabooseRets::Media => [
|
295
301
|
[ :photo_modification_timestamp , :string ],
|
296
302
|
[ :file_name , :string ],
|
data/lib/caboose_rets/version.rb
CHANGED
data/lib/tasks/caboose_rets.rake
CHANGED
@@ -13,7 +13,14 @@ namespace :caboose_rets do
|
|
13
13
|
desc "Do a simple search"
|
14
14
|
task :simple_search => :environment do
|
15
15
|
type = ['p','a','o','oh']
|
16
|
-
@@config =
|
16
|
+
@@config = {
|
17
|
+
'url' => nil,
|
18
|
+
'username' => nil,
|
19
|
+
'password' => nil,
|
20
|
+
'temp_path' => nil,
|
21
|
+
'log_file' => nil,
|
22
|
+
'media_base_url' => nil
|
23
|
+
}
|
17
24
|
config = YAML::load(File.open("#{Rails.root}/config/rets_importer.yml"))
|
18
25
|
config = config[Rails.env]
|
19
26
|
config.each { |key,val| @@config[key] = val }
|
@@ -62,6 +69,62 @@ namespace :caboose_rets do
|
|
62
69
|
end
|
63
70
|
end
|
64
71
|
|
72
|
+
desc "Inspect object"
|
73
|
+
task :inspect, [:search_type, :query] => :environment do |t, args|
|
74
|
+
@@config = {
|
75
|
+
'url' => nil,
|
76
|
+
'username' => nil,
|
77
|
+
'password' => nil,
|
78
|
+
'temp_path' => nil,
|
79
|
+
'log_file' => nil,
|
80
|
+
'media_base_url' => nil
|
81
|
+
}
|
82
|
+
config = YAML::load(File.open("#{Rails.root}/config/rets_importer.yml"))
|
83
|
+
config = config[Rails.env]
|
84
|
+
config.each { |key,val| @@config[key] = val }
|
85
|
+
client = RETS::Client.login(
|
86
|
+
:url => config['url'],
|
87
|
+
:username => config['username'],
|
88
|
+
:password => config['password']
|
89
|
+
)
|
90
|
+
if args.search_type == 'Property'
|
91
|
+
params = {
|
92
|
+
:search_type => 'Property',
|
93
|
+
:class => 'Property',
|
94
|
+
:query => "(ListingId=#{args.query})",
|
95
|
+
:limit => 1,
|
96
|
+
:timeout => -1
|
97
|
+
}
|
98
|
+
elsif args.search_type == 'Agent'
|
99
|
+
params = {
|
100
|
+
:search_type => 'Member',
|
101
|
+
:class => 'Member',
|
102
|
+
:query => "(MemberMlsId=#{args.query})",
|
103
|
+
:limit => 1,
|
104
|
+
:timeout => -1
|
105
|
+
}
|
106
|
+
elsif args.search_type == 'Office'
|
107
|
+
params = {
|
108
|
+
:search_type => 'Office',
|
109
|
+
:class => 'Office',
|
110
|
+
:query => "(OfficeMlsId=#{args.query})",
|
111
|
+
:limit => 1,
|
112
|
+
:timeout => -1
|
113
|
+
}
|
114
|
+
elsif args.search_type == 'OpenHouse'
|
115
|
+
params = {
|
116
|
+
:search_type => 'OpenHouse',
|
117
|
+
:class => 'OpenHouse',
|
118
|
+
:query => "(OpenHouseKey=#{args.query})",
|
119
|
+
:limit => 1,
|
120
|
+
:timeout => -1
|
121
|
+
}
|
122
|
+
end
|
123
|
+
client.search(params) do |data|
|
124
|
+
ap data
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
65
128
|
desc "Import Image"
|
66
129
|
task :img => :environment do
|
67
130
|
CabooseRets::RetsImporter.download_missing_images
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: caboose-rets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.74
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Barry
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: caboose-cms
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- app/helpers/caboose_rets/application_helper.rb
|
49
49
|
- app/models/caboose_rets/agent.rb
|
50
50
|
- app/models/caboose_rets/agent_meta.rb
|
51
|
+
- app/models/caboose_rets/log.rb
|
51
52
|
- app/models/caboose_rets/media.rb
|
52
53
|
- app/models/caboose_rets/office.rb
|
53
54
|
- app/models/caboose_rets/office_meta.rb
|