caboose-rets 0.1.18 → 0.1.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/caboose_rets/admin_media.js +7 -7
- data/app/assets/javascripts/caboose_rets/caboose_rets.js +8 -8
- data/app/controllers/caboose_rets/agents_controller.rb +67 -75
- data/app/controllers/caboose_rets/offices_controller.rb +4 -4
- data/app/controllers/caboose_rets/open_houses_controller.rb +3 -3
- data/app/controllers/caboose_rets/properties_controller.rb +160 -0
- data/app/controllers/caboose_rets/rets_controller.rb +2 -2
- data/app/controllers/caboose_rets/rets_media_controller.rb +13 -13
- data/app/controllers/caboose_rets/saved_properties_controller.rb +35 -35
- data/app/models/caboose_rets/agent.rb +42 -55
- data/app/models/caboose_rets/agent_meta.rb +7 -7
- data/app/models/caboose_rets/media.rb +63 -57
- data/app/models/caboose_rets/office.rb +35 -21
- data/app/models/caboose_rets/open_house.rb +15 -15
- data/app/models/caboose_rets/property.rb +203 -0
- data/app/models/caboose_rets/rets_importer.rb +193 -233
- data/app/models/caboose_rets/rets_importer_bak.rb +77 -77
- data/app/models/caboose_rets/rets_importer_old.rb +625 -0
- data/app/models/caboose_rets/saved_property.rb +4 -4
- data/app/models/caboose_rets/saved_search.rb +36 -33
- data/app/models/caboose_rets/schema.rb +324 -855
- data/app/models/caboose_rets/schema_past.rb +918 -0
- data/app/models/caboose_rets/search_option.rb +6 -6
- data/app/views/caboose/blocks/_layout_rets.html.erb +9 -6
- data/app/views/caboose/blocks/_rets_agent_listings.html.erb +3 -3
- data/app/views/caboose_rets/agents/index.html.erb +23 -40
- data/app/views/caboose_rets/media/admin_property_media.html.erb +2 -2
- data/app/views/caboose_rets/{residential → properties}/_search_form.html.erb +42 -42
- data/app/views/caboose_rets/{residential → properties}/admin_edit.html.erb +7 -7
- data/app/views/caboose_rets/{land → properties}/admin_index.html.erb +11 -11
- data/app/views/caboose_rets/properties/details.html.erb +127 -0
- data/app/views/caboose_rets/{land → properties}/index.html.erb +0 -0
- data/app/views/caboose_rets/{residential/residential_not_exists.html.erb → properties/property_not_exists.html.erb} +4 -5
- data/app/views/caboose_rets/{residential → properties}/test_form.html.erb +1 -1
- data/app/views/caboose_rets/rets/admin_import_form.html.erb +1 -1
- data/config/routes.rb +70 -55
- data/lib/caboose-rets.rb +1 -1
- data/lib/caboose_rets/engine.rb +3 -3
- data/lib/caboose_rets/version.rb +1 -1
- data/lib/rets/base/core.rb +1 -1
- data/lib/rets/base/sax_search.rb +1 -1
- data/lib/tasks/caboose_rets.rake +106 -17
- metadata +16 -50
- data/app/controllers/caboose_rets/commercial_controller.rb +0 -349
- data/app/controllers/caboose_rets/land_controller.rb +0 -144
- data/app/controllers/caboose_rets/multi_family_controller.rb +0 -107
- data/app/controllers/caboose_rets/residential_controller.rb +0 -163
- data/app/models/caboose_rets/commercial_property.rb +0 -214
- data/app/models/caboose_rets/land_property.rb +0 -144
- data/app/models/caboose_rets/multi_family_property.rb +0 -199
- data/app/models/caboose_rets/residential_property.rb +0 -236
- data/app/views/caboose/blocks/_rets_commercial_details.html.erb +0 -192
- data/app/views/caboose/blocks/_rets_commercial_headers.html.erb +0 -17
- data/app/views/caboose/blocks/_rets_commercial_index.html.erb +0 -71
- data/app/views/caboose/blocks/_rets_commercial_row.html.erb +0 -39
- data/app/views/caboose/blocks/_rets_commercial_search_form.html.erb +0 -201
- data/app/views/caboose/blocks/_rets_land_details.html.erb +0 -165
- data/app/views/caboose/blocks/_rets_land_index.html.erb +0 -63
- data/app/views/caboose/blocks/_rets_land_row.html.erb +0 -58
- data/app/views/caboose/blocks/_rets_land_search_form.html.erb +0 -194
- data/app/views/caboose/blocks/_rets_multifamily_details.html.erb +0 -161
- data/app/views/caboose/blocks/_rets_multifamily_index.html.erb +0 -63
- data/app/views/caboose/blocks/_rets_multifamily_row.html.erb +0 -56
- data/app/views/caboose/blocks/_rets_multifamily_search_form.html.erb +0 -273
- data/app/views/caboose/blocks/_rets_openhouse_details.html.erb +0 -12
- data/app/views/caboose/blocks/_rets_openhouses_index.html.erb +0 -79
- data/app/views/caboose/blocks/_rets_residential_details.html.erb +0 -243
- data/app/views/caboose/blocks/_rets_residential_index.html.erb +0 -65
- data/app/views/caboose/blocks/_rets_residential_row.html.erb +0 -59
- data/app/views/caboose/blocks/_rets_residential_search_form.html.erb +0 -304
- data/app/views/caboose_rets/commercial/admin_edit.html.erb +0 -269
- data/app/views/caboose_rets/commercial/admin_index.html.erb +0 -51
- data/app/views/caboose_rets/commercial/admin_new.html.erb +0 -57
- data/app/views/caboose_rets/commercial/details.html.erb +0 -0
- data/app/views/caboose_rets/commercial/index.html.erb +0 -87
- data/app/views/caboose_rets/land/admin_edit.html.erb +0 -156
- data/app/views/caboose_rets/land/details.html.erb +0 -0
- data/app/views/caboose_rets/multi_family/admin_edit.html.erb +0 -211
- data/app/views/caboose_rets/multi_family/admin_index.html.erb +0 -46
- data/app/views/caboose_rets/residential/admin_index.html.erb +0 -46
- data/app/views/caboose_rets/residential/details.html.erb +0 -0
- data/app/views/caboose_rets/residential/index.html.erb +0 -0
@@ -2,8 +2,8 @@
|
|
2
2
|
class CabooseRets::Office < ActiveRecord::Base
|
3
3
|
self.table_name = "rets_offices"
|
4
4
|
|
5
|
-
has_one :meta, :
|
6
|
-
attr_accessible :id, :name, :
|
5
|
+
has_one :meta, :primary_key => 'matrix_unique_id', :foreign_key => 'matrix_unique_id'
|
6
|
+
attr_accessible :id, :name, :lo_mls_id, :matrix_unique_id
|
7
7
|
|
8
8
|
def image
|
9
9
|
return nil if self.meta.nil?
|
@@ -11,24 +11,38 @@ class CabooseRets::Office < ActiveRecord::Base
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def parse(data)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
14
|
+
self.lo_addr1 = data['Addr1']
|
15
|
+
self.lo_addr2 = data['Addr2']
|
16
|
+
self.lo_city = data['City']
|
17
|
+
self.lo_email = data['Email']
|
18
|
+
self.lo_fax_phone = data['FaxPhone']
|
19
|
+
self.lo_mail_addr = data['MailAddr']
|
20
|
+
self.lo_mail_care_of = data['MailCareOf']
|
21
|
+
self.lo_mail_city = data['MailCity']
|
22
|
+
self.lo_mail_postal_code = data['MailPostalCode']
|
23
|
+
self.lo_mail_postal_code_plus4 = data['MailPostalCodePlus4']
|
24
|
+
self.lo_mail_state_or_province = data['MailStatOrProvince']
|
25
|
+
self.matrix_unique_id = data['Matrix_Unique_ID']
|
26
|
+
self.lo_matrix_modified_dt = data['MatrixModifiedDT']
|
27
|
+
self.lo_mls = data['MLS']
|
28
|
+
self.lo_mls_id = data['MLSID']
|
29
|
+
self.lo_office_contact_mui = data['OfficeContact_MUI']
|
30
|
+
self.lo_office_contact_mls_id = data['OfficeContactMLSID']
|
31
|
+
self.lo_office_long_name = data['OfficeLongName']
|
32
|
+
self.lo_office_name = data['OfficeName']
|
33
|
+
self.lo_phone = data['Phone']
|
34
|
+
self.lo_photo_count = data['PhotoCount']
|
35
|
+
self.photo_modification_timestamp = data['PhotoModificationTimestamp']
|
36
|
+
self.state = data['State']
|
37
|
+
self.street_address = data['StreetAddress']
|
38
|
+
self.street_city = data['StreetCity']
|
39
|
+
self.street_postal_code = data['StreetPostalCode']
|
40
|
+
self.street_postal_code_plus4 = data['StreetPostalCodePlus4']
|
41
|
+
self.street_state_or_province = data['StreeStateOrProvince']
|
42
|
+
self.web_facebook = data['WebFacebook']
|
43
|
+
self.web_linked_in = data['WebLinkedIn']
|
44
|
+
self.web_page_address = data['WebPageAddress']
|
45
|
+
self.web_twitter = data['WebTwitter']
|
46
|
+
self.zip = data['ZIP']
|
33
47
|
end
|
34
48
|
end
|
@@ -2,10 +2,10 @@
|
|
2
2
|
class CabooseRets::OpenHouse < ActiveRecord::Base
|
3
3
|
self.table_name = "rets_open_houses"
|
4
4
|
|
5
|
-
attr_accessible :id
|
5
|
+
attr_accessible :id, :matrix_unique_id
|
6
6
|
|
7
7
|
def property
|
8
|
-
models = [CabooseRets::
|
8
|
+
models = [CabooseRets::Property]
|
9
9
|
models.each do |model|
|
10
10
|
id = self.mls_acct.to_i
|
11
11
|
return model.find(id) if model.exists?(id)
|
@@ -14,22 +14,22 @@ class CabooseRets::OpenHouse < ActiveRecord::Base
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def agent
|
17
|
-
return CabooseRets::Agent.where(:
|
17
|
+
return CabooseRets::Agent.where(:mls_id => self.mls_id).first if CabooseRets::Agent.exists?(:mls_id => self.mls_id)
|
18
18
|
return nil
|
19
19
|
end
|
20
20
|
|
21
21
|
def parse(data)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
self.active_yn = data['ActiveYN']
|
23
|
+
self.description = data['Description']
|
24
|
+
self.end_time = data['EndTime']
|
25
|
+
self.entry_order = data['EntryOrder']
|
26
|
+
self.listing_mui = data['ListingMUI']
|
27
|
+
self.matrix_unique_id = data['matrix_unique_id']
|
28
|
+
self.matrix_modified_dt = data['MatrixModifiedDT']
|
29
|
+
self.open_house_date = data['OpenHouseDate']
|
30
|
+
self.open_house_type = data['OpenHouseType']
|
31
|
+
self.provider_key = data['ProviderKey']
|
32
|
+
self.refreshments = data['Refrehments']
|
33
|
+
self.start_time = data['StartTime']
|
34
34
|
end
|
35
35
|
end
|
@@ -0,0 +1,203 @@
|
|
1
|
+
class CabooseRets::Property <ActiveRecord::Base
|
2
|
+
self.table_name = "rets_properties"
|
3
|
+
attr_accessible :id, :matrix_unique_id
|
4
|
+
|
5
|
+
def url() return "/property/#{self.id}" end
|
6
|
+
def images() return CabooseRets::Media.where(:media_mui => self.matrix_unique_id, :media_type => 'Photo').reorder(:media_order).all end
|
7
|
+
def files() return CabooseRets::Media.where(:media_mui => self.matrix_unique_id, :media_type => 'File' ).reorder(:media_order).all end
|
8
|
+
def virtual_tour
|
9
|
+
return nil if !CabooseRets::Media.where(:mls => self.mls.to_s).where(:media_type => 'Virtual Tour').exists?
|
10
|
+
media = CabooseRets::Media.where(:mls => self.mls.to_s, :media_type => 'Virtual Tour').first
|
11
|
+
return media.url
|
12
|
+
end
|
13
|
+
def self.geolocatable() all(conditions: "latitude IS NOT NULL AND longitude IS NOT NULL") end
|
14
|
+
|
15
|
+
def refresh_from_mls
|
16
|
+
CabooseRets::RetsImporter.import_property(self.matrix_unique_id)
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse(data)
|
20
|
+
self.access = data['Access']
|
21
|
+
self.acreage = data['Acreage']
|
22
|
+
self.acreage_source = data['AcreageSource']
|
23
|
+
self.active_open_house_count = data['ActiveOpenHouseCount']
|
24
|
+
self.adjoining_land_use = data['AdjoiningLandUse']
|
25
|
+
self.age = data['Age']
|
26
|
+
self.annual_taxes = data['AnnualTaxes']
|
27
|
+
self.appliances = data['Appliances']
|
28
|
+
self.area = data['Area']
|
29
|
+
self.attic = data['Attic']
|
30
|
+
self.available_date = data['AvailableDate']
|
31
|
+
self.basement = data['Basement']
|
32
|
+
self.basement_yn = data['BasementYN']
|
33
|
+
self.baths_full = data['BathsFull']
|
34
|
+
self.baths_half = data['BathsHalf']
|
35
|
+
self.baths_total = data['BathsTotal']
|
36
|
+
self.beds_total = data['BedsTotal']
|
37
|
+
self.book_number = data['BookNumber']
|
38
|
+
self.book_page = data['BookPage']
|
39
|
+
self.book_type = data['BookType']
|
40
|
+
self.building_type = data['BuildingType']
|
41
|
+
self.business_included_yn = data['BusinessIncludedYN']
|
42
|
+
self.buyer_name = data['BuyerName']
|
43
|
+
self.city = data['City']
|
44
|
+
self.city_community = data['CityCommunity']
|
45
|
+
self.closing = data['Closing']
|
46
|
+
self.co_list_agent_mui = data['CoListAgent_MUI']
|
47
|
+
self.co_list_agent_direct_work_phone = data['CoListAgentDirectWorkPhone']
|
48
|
+
self.co_list_agent_email = data['CoListAgentEmail']
|
49
|
+
self.co_list_agent_full_name = data['CoListAgentFullName']
|
50
|
+
self.co_list_agent_mls_id = data['CoListAgentMLSID']
|
51
|
+
self.co_list_office_mui = data['CoListOffice_MUI']
|
52
|
+
self.co_list_office_mls_id = data['CoListOfficeMLSID']
|
53
|
+
self.co_list_office_name = data['CoListOfficeName']
|
54
|
+
self.co_list_office_phone = data['CoListOfficePhone']
|
55
|
+
self.completion_date = data['CompletionDate']
|
56
|
+
self.comp_tenant_rep = data['CompTenantRep']
|
57
|
+
self.construction = data['Construction']
|
58
|
+
self.construction_status = data['ConstructionStatus']
|
59
|
+
self.cooling = data['Cooling']
|
60
|
+
self.county_or_parish = data['CountyOrParish']
|
61
|
+
self.deposit = data['Deposit']
|
62
|
+
self.dining_room = data['DiningRoom']
|
63
|
+
self.directions = data['Directions']
|
64
|
+
self.display_address_on_internet_yn = data['DisplayAddressOnInternetYN']
|
65
|
+
self.dom = data['DOM']
|
66
|
+
self.driveway = data['Driveway']
|
67
|
+
self.elementary_school = data['ElementarySchool']
|
68
|
+
self.exists_struct = data['ExistStruct']
|
69
|
+
self.expenses_association = data['ExpensesAssociation']
|
70
|
+
self.expenses_insurance = data['ExpensesInsurance']
|
71
|
+
self.expenses_maintenance = data['ExpensesMaintenance']
|
72
|
+
self.expenses_management = data['ExpensesManagement']
|
73
|
+
self.expenses_other = data['ExpensesOther']
|
74
|
+
self.expenses_tax = data['ExpensesTax']
|
75
|
+
self.expenses_utility = data['ExpensesUtility']
|
76
|
+
self.exterior_features = data['ExteriorFeatures']
|
77
|
+
self.fireplace = data['Fireplace']
|
78
|
+
self.flood_plain = data['FloodPlain']
|
79
|
+
self.flooring = data['Flooring']
|
80
|
+
self.foreclosure_sale_date = data['ForeclosureSaleDate']
|
81
|
+
self.foreclosure_yn = data['ForeclosureYN']
|
82
|
+
self.fsboyn = data['FSBOYN']
|
83
|
+
self.garage = data['Garage']
|
84
|
+
self.heating = data['Heating']
|
85
|
+
self.high_school = data['HighSchool']
|
86
|
+
self.hoa_amenities = data['HOAAmenities']
|
87
|
+
self.hoa_fee = data['HOAFee']
|
88
|
+
self.hoa_included_in_rent_yn = data['HOAIncludedInRentYN']
|
89
|
+
self.hoa_term = data['HOATerm']
|
90
|
+
self.hoa_term_mandatory_yn = data['HOATermMandatoryYN']
|
91
|
+
self.homestead_yn = data['HomesteadYN']
|
92
|
+
self.idx_opt_in_yn = data['IDXOptInYN']
|
93
|
+
self.income_other = data['IncomeOther']
|
94
|
+
self.income_rental = data['IncomeRental']
|
95
|
+
self.interior_features = data['InteriorFeatures']
|
96
|
+
self.land_features_extras = data['LandFeaturesExtras']
|
97
|
+
self.landscaping = data['Landscaping']
|
98
|
+
self.laundry = data['Laundry']
|
99
|
+
self.legal_description = data['LegalDescription']
|
100
|
+
self.legal_lot = data['LegalLot']
|
101
|
+
self.legal_section = data['LegalSection']
|
102
|
+
self.levels = data['Levels']
|
103
|
+
self.list_agent_mui = data['ListAgent_MUI']
|
104
|
+
self.list_agent_direct_work_phone = data['ListAgentDirectWorkPhone']
|
105
|
+
self.list_agent_email = data['ListAgentEmail']
|
106
|
+
self.list_agent_full_name = data['ListAgentFullName']
|
107
|
+
self.list_agent_mls_id = data['ListAgentMLSID']
|
108
|
+
self.listing_contract_date = data['ListingContractDate']
|
109
|
+
self.list_office_mui = data['ListOffice_MUI']
|
110
|
+
self.list_office_mls_id = data['ListOfficeMLSID']
|
111
|
+
self.list_office_name = data['ListOfficeName']
|
112
|
+
self.list_office_phone = data['ListOfficePhone']
|
113
|
+
self.list_price = data['ListPrice']
|
114
|
+
self.lot_description = data['LotDescription']
|
115
|
+
self.lot_dimensions = data['LotDimensions']
|
116
|
+
self.lot_dim_source = data['LotDimSource']
|
117
|
+
self.management = data['Management']
|
118
|
+
self.master_bed_level = data['MasterBedLevel']
|
119
|
+
self.matrix_unique_id = data['Matrix_Unique_ID']
|
120
|
+
self.matrix_modified_dt = data['MatrixModifiedDT']
|
121
|
+
self.max_sqft = data['MaxSqft']
|
122
|
+
self.middle_school = data['MiddleSchool']
|
123
|
+
self.mineral_rights = data['MineralRights']
|
124
|
+
self.min_sqft = data['MinSqft']
|
125
|
+
self.misc_indoor_featuresa = data['MiscIndoorFeatures']
|
126
|
+
self.mls = data['MLS']
|
127
|
+
self.mls_number = data['MLSNumber']
|
128
|
+
self.municipality = data['Municipality']
|
129
|
+
self.net_op_inc = data['NetOpInc']
|
130
|
+
self.open_house_count = data['OpenHouseCount']
|
131
|
+
self.open_house_public_count = data['OpenHousePublicCount']
|
132
|
+
self.open_house_public_upcoming = data['OpenHousePublicUpcoming']
|
133
|
+
self.open_house_upcoming = data['OpenHouseUpcoming']
|
134
|
+
self.parcel_number = data['ParcelNumber']
|
135
|
+
self.pending_date = data['PendingDate']
|
136
|
+
self.pets_allowed_yn = data['PetsAllowedYN']
|
137
|
+
self.photo_count = data['PhotoCount']
|
138
|
+
self.photo_modification_timestamp = data['PhotoModificationTimestamp']
|
139
|
+
self.pool = data['Pool']
|
140
|
+
self.porch_patio = data['PorchPatio']
|
141
|
+
self.possession = data['Possession']
|
142
|
+
self.possible_uses = data['PossibleUses']
|
143
|
+
self.postal_code = data['PostalCode']
|
144
|
+
self.postal_code_plus4 = data['PostalCodePlus4']
|
145
|
+
self.price_per_acre = data['PricePerAcre']
|
146
|
+
self.price_sqft = data['PriceSqft']
|
147
|
+
self.property_name = data['PropertyName']
|
148
|
+
self.property_subtype = data['PropertySubType']
|
149
|
+
self.property_type = data['PropertyType']
|
150
|
+
self.property_use = data['PropertyUse']
|
151
|
+
self.prop_mgmt_comp = data['PropMgmtComp']
|
152
|
+
self.public_remarks = data['PublicRemarks']
|
153
|
+
self.refrigerator_included_yn = data['RefrigeratorIncludedYN']
|
154
|
+
self.rental_rate_type = data['RentalRateType']
|
155
|
+
self.rent_incl = data['RentIncl']
|
156
|
+
self.res_style = data['ResStyle']
|
157
|
+
self.restrictions = data['Restrictions']
|
158
|
+
self.road_frontage = data['RoadFrontage']
|
159
|
+
self.roof = data['Roof']
|
160
|
+
self.roofage = data['Roofage']
|
161
|
+
self.room_count = data['RoomCount']
|
162
|
+
self.service_type = data['ServiceType']
|
163
|
+
self.sewer = data['Sewer']
|
164
|
+
self.sold_terms = data['SoldTerms']
|
165
|
+
self.sprinkler = data['Sprinkler']
|
166
|
+
self.sqft_source = data['SqftSource']
|
167
|
+
self.sqft_total = data['SqFtTotal']
|
168
|
+
self.state_or_province = data['StateOrProvince']
|
169
|
+
self.status = data['Status']
|
170
|
+
self.status_contractual_search_date = data['StatusContractualSearchDate']
|
171
|
+
self.street_dir_prefix = data['StreetDirPrefix']
|
172
|
+
self.street_dir_suffix = data['StreetDirSuffix']
|
173
|
+
self.street_name = data['StreetName']
|
174
|
+
self.street_number = data['StreetNumber']
|
175
|
+
self.street_number_numeric = data['StreetNumberNumeric']
|
176
|
+
self.street_suffix = data['StreetSuffix']
|
177
|
+
self.street_view_param = data['StreetViewParam']
|
178
|
+
self.style = data['Style']
|
179
|
+
self.subdivision = data['Subdivision']
|
180
|
+
self.topography = data['Topography']
|
181
|
+
self.total_num_units = data['TotalNumOfUnits']
|
182
|
+
self.total_num_units_occupied = data['TotalNumOfUnitsOccupied']
|
183
|
+
self.transaction_type = data['TransactionType']
|
184
|
+
self.unit_count = data['UnitCount']
|
185
|
+
self.unit_number = data['UnitNumber']
|
186
|
+
self.utilities = data['Utilities']
|
187
|
+
self.virtual_tour1 = data['VirtualTour1']
|
188
|
+
self.vow_allowed_avmyn = data['VOWAllowAVMYN']
|
189
|
+
self.vow_allowed_third_party_comm_yn = data['VOWAllowThirdPartyCommYN']
|
190
|
+
self.washer_dryer_included = data['WasherDryerIncludedYN']
|
191
|
+
self.water = data['Water']
|
192
|
+
self.waterfronts = data['Waterfronts']
|
193
|
+
self.waterfront_yn = data['WaterfrontYN']
|
194
|
+
self.water_heater = data['WaterHeater']
|
195
|
+
self.windows = data['Windows']
|
196
|
+
self.window_treatments = data['WindowTreatments']
|
197
|
+
self.year_built = data['YearBuilt']
|
198
|
+
self.yr_blt_source = data['YrBltSource']
|
199
|
+
self.zoning = data['Zoning']
|
200
|
+
self.zoning_northport = data['ZoningNorthPort']
|
201
|
+
self.zoning_tusc = data['ZoningTusc']
|
202
|
+
end
|
203
|
+
end
|
@@ -15,7 +15,7 @@ require 'json'
|
|
15
15
|
|
16
16
|
class CabooseRets::RetsImporter # < ActiveRecord::Base
|
17
17
|
|
18
|
-
@@rets_client = nil
|
18
|
+
@@rets_client = nil
|
19
19
|
@@config = nil
|
20
20
|
|
21
21
|
def self.config
|
@@ -31,7 +31,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
31
31
|
'log_file' => nil,
|
32
32
|
'media_base_url' => nil
|
33
33
|
}
|
34
|
-
config = YAML::load(File.open("#{Rails.root}/config/rets_importer.yml"))
|
34
|
+
config = YAML::load(File.open("#{Rails.root}/config/rets_importer.yml"))
|
35
35
|
config = config[Rails.env]
|
36
36
|
config.each { |key,val| @@config[key] = val }
|
37
37
|
end
|
@@ -51,34 +51,31 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
51
51
|
|
52
52
|
def self.meta(class_type)
|
53
53
|
case class_type
|
54
|
-
when '
|
55
|
-
when '
|
56
|
-
when '
|
57
|
-
when '
|
58
|
-
when '
|
59
|
-
|
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
|
54
|
+
when 'Office' then Caboose::StdClass.new({ :search_type => 'Office' , :remote_key_field => 'Matrix_Unique_ID' , :local_key_field => 'matrix_unique_id' , :local_table => 'rets_offices' , :date_modified_field => 'MatrixModifiedDT'})
|
55
|
+
when 'Agent' then Caboose::StdClass.new({ :search_type => 'Agent' , :remote_key_field => 'Matrix_Unique_ID' , :local_key_field => 'matrix_unique_id' , :local_table => 'rets_agents' , :date_modified_field => 'MatrixModifiedDT'})
|
56
|
+
when 'OpenHouse' then Caboose::StdClass.new({ :search_type => 'OpenHouse' , :remote_key_field => 'matrix_unique_id' , :local_key_field => 'matrix_unique_id' , :local_table => 'rets_open_houses' , :date_modified_field => 'MatrixModifiedDT'})
|
57
|
+
when 'Listing' then Caboose::StdClass.new({ :search_type => 'Property' , :remote_key_field => 'Matrix_Unique_ID' , :local_key_field => 'matrix_unique_id' , :local_table => 'rets_properties' , :date_modified_field => 'MatrixModifiedDT'})
|
58
|
+
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' })
|
59
|
+
end
|
63
60
|
end
|
64
61
|
|
65
62
|
#=============================================================================
|
66
63
|
# Import method
|
67
64
|
#=============================================================================
|
68
65
|
|
69
|
-
def self.import(class_type, query)
|
66
|
+
def self.import(class_type, query)
|
70
67
|
m = self.meta(class_type)
|
71
|
-
|
68
|
+
self.log("Importing #{m.search_type}:#{class_type} with query #{query}...")
|
72
69
|
self.get_config if @@config.nil? || @@config['url'].nil?
|
73
70
|
params = {
|
74
71
|
:search_type => m.search_type,
|
75
72
|
:class => class_type,
|
76
73
|
:query => query,
|
77
|
-
:limit => -1,
|
78
74
|
:timeout => -1
|
79
75
|
}
|
80
76
|
obj = nil
|
81
|
-
|
77
|
+
|
78
|
+
begin
|
82
79
|
self.client.search(params) do |data|
|
83
80
|
obj = self.get_instance_with_id(class_type, data)
|
84
81
|
if obj.nil?
|
@@ -93,30 +90,23 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
93
90
|
self.log "Import error for #{class_type}: #{query}"
|
94
91
|
self.log err.message
|
95
92
|
end
|
96
|
-
|
97
93
|
end
|
98
94
|
|
99
95
|
def self.get_instance_with_id(class_type, data)
|
100
96
|
obj = nil
|
101
97
|
m = case class_type
|
102
|
-
when '
|
103
|
-
when '
|
104
|
-
when '
|
105
|
-
when '
|
106
|
-
when '
|
107
|
-
|
108
|
-
|
109
|
-
when '
|
110
|
-
|
111
|
-
|
112
|
-
when '
|
113
|
-
when 'GFX'
|
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'] )
|
98
|
+
when 'Listing' then CabooseRets::Property
|
99
|
+
when 'OpenHouse' then CabooseRets::OpenHouse
|
100
|
+
when 'Agent' then CabooseRets::Agent
|
101
|
+
when 'Office' then CabooseRets::Office
|
102
|
+
when 'GFX' then CabooseRets::Media
|
103
|
+
end
|
104
|
+
obj = case class_type
|
105
|
+
when 'Listing' then m.where(:matrix_unique_id => data['Matrix_Unique_ID']).exists? ? m.where(:matrix_unique_id => data['Matrix_Unique_ID']).first : m.new(:matrix_unique_id => data['Matrix_Unique_ID'])
|
106
|
+
when 'OpenHouse' then m.where(:matrix_unique_id => data['matrix_unique_id']).exists? ? m.where(:matrix_unique_id => data['matrix_unique_id']).first : m.new(:matrix_unique_id => data['matrix_unique_id'])
|
107
|
+
when 'Agent' then m.where(:matrix_unique_id => data['Matrix_Unique_ID']).exists? ? m.where(:matrix_unique_id => data['Matrix_Unique_ID']).first : m.new(:matrix_unique_id => data['Matrix_Unique_ID'])
|
108
|
+
when 'Office' then m.where(:matrix_unique_id => data['Matrix_Unique_ID']).exists? ? m.where(:matrix_unique_id => data['Matrix_Unique_ID']).first : m.new(:matrix_unique_id => data['Matrix_Unique_ID'])
|
109
|
+
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'] )
|
120
110
|
end
|
121
111
|
return obj
|
122
112
|
end
|
@@ -126,36 +116,32 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
126
116
|
#=============================================================================
|
127
117
|
|
128
118
|
def self.update_after(date_modified, save_images = true)
|
129
|
-
self.delay(:queue => 'rets').update_helper('
|
130
|
-
self.delay(:queue => 'rets').update_helper('
|
131
|
-
self.delay(:queue => 'rets').update_helper('
|
132
|
-
self.delay(:queue => 'rets').update_helper('
|
133
|
-
self.delay(:queue => 'rets').update_helper('OFF', date_modified, save_images)
|
134
|
-
self.delay(:queue => 'rets').update_helper('AGT', date_modified, save_images)
|
135
|
-
self.delay(:queue => 'rets').update_helper('OPH', date_modified, save_images)
|
119
|
+
self.delay(:queue => 'rets').update_helper('Listing' , date_modified, save_images)
|
120
|
+
self.delay(:queue => 'rets').update_helper('Office' , date_modified, save_images)
|
121
|
+
self.delay(:queue => 'rets').update_helper('Agent' , date_modified, save_images)
|
122
|
+
self.delay(:queue => 'rets').update_helper('OpenHouse', date_modified, save_images)
|
136
123
|
end
|
137
124
|
|
138
|
-
def self.update_helper(class_type, date_modified, save_images = true)
|
125
|
+
def self.update_helper(class_type, date_modified, save_images = true)
|
139
126
|
m = self.meta(class_type)
|
140
|
-
k = m.remote_key_field
|
141
|
-
d = date_modified.in_time_zone(CabooseRets::timezone).strftime("%FT%T")
|
127
|
+
k = m.remote_key_field
|
128
|
+
d = date_modified.in_time_zone(CabooseRets::timezone).strftime("%FT%T")
|
142
129
|
params = {
|
143
130
|
:search_type => m.search_type,
|
144
131
|
:class => class_type,
|
145
132
|
:select => [m.remote_key_field],
|
133
|
+
:querytype => 'DMQL2',
|
146
134
|
:query => "(#{m.date_modified_field}=#{d}+)",
|
147
135
|
:standard_names_only => true,
|
148
136
|
:timeout => -1
|
149
|
-
}
|
150
|
-
self.
|
137
|
+
}
|
138
|
+
self.log(params)
|
139
|
+
self.client.search(params) do |data|
|
151
140
|
case class_type
|
152
|
-
when '
|
153
|
-
when '
|
154
|
-
when '
|
155
|
-
when '
|
156
|
-
when 'OFF' then self.delay(:priority => 10, :queue => 'rets').import_office( data[k], save_images)
|
157
|
-
when 'AGT' then self.delay(:priority => 10, :queue => 'rets').import_agent( data[k], save_images)
|
158
|
-
when 'OPH' then self.delay(:priority => 10, :queue => 'rets').import_open_house( data[k], save_images)
|
141
|
+
when 'Listing' then self.delay(:priority => 10, :queue => 'rets').import_properties(data[k], save_images)
|
142
|
+
when 'Office' then self.delay(:priority => 10, :queue => 'rets').import_office( data[k], save_images)
|
143
|
+
when 'Agent' then self.delay(:priority => 10, :queue => 'rets').import_agent( data[k], save_images)
|
144
|
+
when 'OpenHouse' then self.delay(:priority => 10, :queue => 'rets').import_open_house(data[k], save_images)
|
159
145
|
end
|
160
146
|
end
|
161
147
|
end
|
@@ -164,115 +150,116 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
164
150
|
# Single model import methods (called from a worker dyno)
|
165
151
|
#=============================================================================
|
166
152
|
|
167
|
-
def self.import_property(
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
153
|
+
# def self.import_property(mui, save_images = true)
|
154
|
+
# self.import('Listinng', "(Matrix_Unique_ID=*#{mui}*)")
|
155
|
+
# p = CabooseRets::Property.where(:id => id.to_i).first
|
156
|
+
# self.download_property_images(p, save_images)
|
157
|
+
# end
|
158
|
+
|
159
|
+
def self.import_properties(mui, save_images = true)
|
160
|
+
self.import('Listing', "(Matrix_Unique_ID=#{mui})")
|
161
|
+
p = CabooseRets::Property.where(:matrix_unique_id => mui.to_s).first
|
162
|
+
# p = CabooseRets::Property.create(:matrix_unique_id => mui.to_s) if p.nil?
|
163
|
+
if p != nil
|
164
|
+
self.download_property_images(p)
|
165
|
+
self.update_coords(p)
|
166
|
+
else
|
167
|
+
self.log("No Property associated with #{mui}")
|
182
168
|
end
|
183
|
-
self.download_property_images(p, save_images)
|
184
|
-
end
|
185
|
-
|
186
|
-
def self.import_residential_property(mls_acct, save_images = true)
|
187
|
-
self.import('RES', "(MLS_ACCT=*#{mls_acct}*)")
|
188
|
-
p = CabooseRets::ResidentialProperty.where(:id => mls_acct.to_i).first
|
189
|
-
self.download_property_images(p, save_images)
|
190
|
-
self.update_coords(p)
|
191
|
-
end
|
192
|
-
|
193
|
-
def self.import_commercial_property(mls_acct, save_images = true)
|
194
|
-
self.import('COM', "(MLS_ACCT=*#{mls_acct}*)")
|
195
|
-
p = CabooseRets::CommercialProperty.where(:id => mls_acct.to_i).first
|
196
|
-
self.download_property_images(p, save_images)
|
197
|
-
self.update_coords(p)
|
198
|
-
end
|
199
|
-
|
200
|
-
def self.import_land_property(mls_acct, save_images = true)
|
201
|
-
self.import('LND', "(MLS_ACCT=*#{mls_acct}*)")
|
202
|
-
p = CabooseRets::LandProperty.where(:id => mls_acct.to_i).first
|
203
|
-
self.download_property_images(p, save_images)
|
204
|
-
self.update_coords(p)
|
205
|
-
end
|
206
|
-
|
207
|
-
def self.import_multi_family_property(mls_acct, save_images = true)
|
208
|
-
self.import('MUL', "(MLS_ACCT=*#{mls_acct}*)")
|
209
|
-
p = CabooseRets::MultiFamilyProperty.where(:id => mls_acct.to_i).first
|
210
|
-
self.download_property_images(p, save_images)
|
211
|
-
self.update_coords(p)
|
212
169
|
end
|
213
170
|
|
214
|
-
def self.import_office(
|
215
|
-
self.import('
|
216
|
-
office = CabooseRets::Office.where(:
|
217
|
-
self.download_office_image(office) if save_images == true
|
171
|
+
def self.import_office(mui, save_images = true)
|
172
|
+
self.import('Office', "(matrix_unique_id=#{mui})")
|
173
|
+
office = CabooseRets::Office.where(:matrix_unique_id => mui.to_s).first
|
174
|
+
# self.download_office_image(office) if save_images == true
|
218
175
|
end
|
219
176
|
|
220
|
-
def self.import_agent(
|
221
|
-
self.import('
|
222
|
-
a = CabooseRets::Agent.where(:
|
223
|
-
self.download_agent_image(a) #if save_images == true
|
177
|
+
def self.import_agent(mui, save_images = true)
|
178
|
+
self.import('Agent', "(Matrix_Unique_ID=#{mui})")
|
179
|
+
a = CabooseRets::Agent.where(:matrix_unique_id => mui.to_s).first
|
180
|
+
# self.download_agent_image(a) #if save_images == true
|
224
181
|
end
|
225
182
|
|
226
|
-
def self.import_open_house(
|
227
|
-
self.import('
|
183
|
+
def self.import_open_house(mui, save_images = true)
|
184
|
+
self.import('OpenHouse', "(Matrix_Unique_ID=#{mui})")
|
228
185
|
end
|
229
186
|
|
230
187
|
def self.import_media(id, save_images = true)
|
231
|
-
self.import('GFX', "((MEDIA_ID=#{id}+),(MEDIA_ID=#{id}-))")
|
188
|
+
self.import('GFX', "((MEDIA_ID=#{id}+),(MEDIA_ID=#{id}-))")
|
232
189
|
end
|
233
190
|
|
234
191
|
#=============================================================================
|
235
192
|
# Images
|
236
193
|
#=============================================================================
|
237
|
-
|
238
|
-
def self.download_property_images(p, save_images = true)
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
194
|
+
|
195
|
+
# def self.download_property_images(p, save_images = true)
|
196
|
+
# return if save_images == false
|
197
|
+
|
198
|
+
# self.log("- Downloading GFX records for #{p.matrix_unique_id}...")
|
199
|
+
# params = {
|
200
|
+
# :search_type => 'Media',
|
201
|
+
# :class => 'Photo',
|
202
|
+
# :type => 'Photo',
|
203
|
+
# :resource => 'Property',
|
204
|
+
# :query => "(ID=*#{p.matrix_unique_id}:1*)",
|
205
|
+
# :limit => 1000,
|
206
|
+
# :timeout => -1
|
207
|
+
# }
|
208
|
+
# ids = []
|
209
|
+
# self.client.search(params) do |data|
|
210
|
+
# puts data
|
211
|
+
# ids << data['MEDIA_ID']
|
212
|
+
# m = CabooseRets::Media.where(:media_id => data['MEDIA_ID']).first
|
213
|
+
# m = CabooseRets::Media.new if m.nil?
|
214
|
+
# data.MEDIA_MUI = p.matrix_unique_id
|
215
|
+
# m.parse(data)
|
216
|
+
# m.save
|
217
|
+
# end
|
218
|
+
|
219
|
+
# if ids.count > 0
|
220
|
+
# # Delete any records in the local database that shouldn't be there
|
221
|
+
# self.log("- Deleting GFX records for MLS ##{p.matrix_unique_id} in the local database that are not in the remote database...")
|
222
|
+
# query = "select media_id from rets_media where matrix_unique_id = '#{p.matrix_unique_id}'"
|
223
|
+
# rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
224
|
+
# local_ids = rows.collect{ |row| row['media_id'] }
|
225
|
+
# ids_to_remove = local_ids - ids
|
226
|
+
# if ids_to_remove && ids_to_remove.count > 0
|
227
|
+
# query = ["delete from rets_media where media_id in (?)", ids_to_remove]
|
228
|
+
# ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
229
|
+
# end
|
230
|
+
# end
|
231
|
+
# end
|
232
|
+
|
233
|
+
def self.download_property_images(p)
|
234
|
+
self.log "Saving images for #{p.matrix_unique_id}..."
|
235
|
+
i=0
|
236
|
+
begin
|
237
|
+
url = "http://rets.wamls.mlsmatrix.com/rets/GetObject.ashx?Type=Photo&Resource=Property&ID=1026514:1"
|
238
|
+
self.client.get_object(:resource => 'Property', :type => 'Photo', :location=> false, :id => '1026514:*') do |headers, content|
|
239
|
+
m = CabooseRets::Media.where(:media_mui => headers['object-id']).first
|
240
|
+
m = CabooseRets::Media.new if m.nil?
|
241
|
+
m.media = Caboose::Media.new
|
242
|
+
File.open("temp_img_#{p.matrix_unique_id}_#{i}.jpeg", "wb") do |f|
|
243
|
+
f.write(content)
|
244
|
+
end
|
245
|
+
m.media.image = File.open("temp_img_#{p.matrix_unique_id}_#{i}.jpeg")
|
246
|
+
m.media_type = headers['content_type']
|
247
|
+
m.media_mui = headers['media_mui']
|
248
|
+
m.media.save
|
249
|
+
m.save
|
250
|
+
self.log("Image #{p.matrix_unique_id}"+ ":#{i} saved")
|
251
|
+
i += 1
|
267
252
|
end
|
253
|
+
rescue RETS::APIError => err
|
254
|
+
self.log "No image for #{p.matrix_unique_id}."
|
255
|
+
self.log err
|
268
256
|
end
|
269
|
-
|
270
257
|
end
|
271
|
-
|
258
|
+
|
272
259
|
def self.download_agent_image(agent)
|
273
260
|
self.log "Saving image for #{agent.first_name} #{agent.last_name}..."
|
274
261
|
begin
|
275
|
-
self.client.get_object(:resource => :Agent, :type => :Photo, :location => true, :id =>
|
262
|
+
self.client.get_object(:resource => :Agent, :type => :Photo, :location => true, :id => property.list_agent_mls_id) do |headers, content|
|
276
263
|
agent.verify_meta_exists
|
277
264
|
agent.meta.image_location = headers['location']
|
278
265
|
agent.meta.save
|
@@ -282,7 +269,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
282
269
|
self.log err
|
283
270
|
end
|
284
271
|
end
|
285
|
-
|
272
|
+
|
286
273
|
def self.download_office_image(office)
|
287
274
|
#self.log "Saving image for #{agent.first_name} #{agent.last_name}..."
|
288
275
|
#begin
|
@@ -303,23 +290,19 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
303
290
|
|
304
291
|
def self.update_coords(p = nil)
|
305
292
|
if p.nil?
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
model.where(:latitude => nil).reorder(:mls_acct).each do |p|
|
312
|
-
self.delay(:queue => 'rets').update_coords(p)
|
293
|
+
model = CabooseRets::Property
|
294
|
+
i = 0
|
295
|
+
self.log "Updating coords properties..."
|
296
|
+
model.where(:latitude => nil).reorder(:matrix_unique_id).each do |p1|
|
297
|
+
self.delay(:queue => 'rets').update_coords(p1)
|
313
298
|
end
|
314
|
-
i = i + 1
|
315
|
-
end
|
316
299
|
return
|
317
300
|
end
|
318
301
|
|
319
|
-
self.log "Getting coords for
|
320
|
-
coords = self.coords_from_address(CGI::escape "#{p.
|
302
|
+
self.log "Getting coords for Matrix_Unique_ID #{p.matrix_unique_id}..."
|
303
|
+
coords = self.coords_from_address(CGI::escape "#{p.street_number} #{p.street_name}, #{p.city}, #{p.state_or_province} #{p.postal_code}")
|
321
304
|
if coords.nil? || coords == false
|
322
|
-
self.log "Can't set coords for
|
305
|
+
self.log "Can't set coords for Matrix_Unique_ID #{p.Matrix_Unique_ID}..."
|
323
306
|
return
|
324
307
|
end
|
325
308
|
|
@@ -348,30 +331,25 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
348
331
|
#=============================================================================
|
349
332
|
|
350
333
|
def self.purge
|
351
|
-
self.
|
352
|
-
self.
|
353
|
-
self.purge_land
|
354
|
-
self.purge_multi_family
|
334
|
+
self.log('purging')
|
335
|
+
self.purge_properties
|
355
336
|
self.purge_offices
|
356
337
|
#self.purge_agents
|
357
338
|
self.purge_open_houses
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
def self.
|
362
|
-
def self.
|
363
|
-
def self.
|
364
|
-
|
365
|
-
def self.purge_offices() self.delay(:queue => 'rets').purge_helper('OFF', '2012-01-01') end
|
366
|
-
def self.purge_agents() self.delay(:queue => 'rets').purge_helper('AGT', '2012-01-01') end
|
367
|
-
def self.purge_open_houses() self.delay(:queue => 'rets').purge_helper('OPH', '2012-01-01') end
|
368
|
-
def self.purge_media() self.delay(:queue => 'rets').purge_helper('GFX', '2012-01-01') end
|
339
|
+
end
|
340
|
+
|
341
|
+
def self.purge_properties() self.delay(:queue => 'rets').purge_helper('Listing', '2012-01-01') end
|
342
|
+
def self.purge_offices() self.delay(:queue => 'rets').purge_helper('Office', '2012-01-01') end
|
343
|
+
def self.purge_agents() self.delay(:queue => 'rets').purge_helper('Agent', '2012-01-01') end
|
344
|
+
def self.purge_open_houses() self.delay(:queue => 'rets').purge_helper('OpenHouse', '2012-01-01') end
|
345
|
+
|
369
346
|
|
370
|
-
def self.purge_helper(class_type, date_modified)
|
371
|
-
m = self.meta(class_type)
|
347
|
+
def self.purge_helper(class_type, date_modified)
|
348
|
+
m = self.meta(class_type)
|
349
|
+
self.log(m.search_type)
|
372
350
|
|
373
351
|
self.log("Purging #{class_type}...")
|
374
|
-
|
352
|
+
|
375
353
|
# Get the total number of records
|
376
354
|
self.log("- Getting total number of records for #{class_type}...")
|
377
355
|
params = {
|
@@ -381,35 +359,36 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
381
359
|
:standard_names_only => true,
|
382
360
|
:timeout => -1
|
383
361
|
}
|
384
|
-
|
385
|
-
|
362
|
+
count = 0
|
363
|
+
self.client.search(params.merge({ :count => 1})) do |data| end
|
364
|
+
count = self.client.rets_data[:code] == "20201" ? 0 : self.client.rets_data[:count]
|
386
365
|
batch_count = (count.to_f/5000.0).ceil
|
387
|
-
|
366
|
+
|
388
367
|
ids = []
|
389
368
|
k = m.remote_key_field
|
390
369
|
(0...batch_count).each do |i|
|
391
370
|
self.log("- Getting ids for #{class_type} (batch #{i+1} of #{batch_count})...")
|
392
|
-
self.client.search(params.merge({ :select => [k], :limit => 5000, :offset => 5000*i })) do |data|
|
393
|
-
ids << (class_type == '
|
394
|
-
end
|
395
|
-
end
|
371
|
+
self.client.search(params.merge({ :select => [k], :limit => 5000, :offset => 5000*i })) do |data|
|
372
|
+
ids << (class_type == 'OpenHouse' ? data[k].to_i : data[k])
|
373
|
+
end
|
374
|
+
end
|
396
375
|
|
397
|
-
# Only do stuff if we got a real response from the server
|
376
|
+
# Only do stuff if we got a real response from the server
|
398
377
|
if ids.count > 0
|
399
|
-
|
378
|
+
|
400
379
|
# Delete any records in the local database that shouldn't be there
|
401
|
-
self.log("- Finding #{class_type} records in the local database that are not in the remote database...")
|
380
|
+
self.log("- Finding #{class_type} records in the local database that are not in the remote database...")
|
402
381
|
t = m.local_table
|
403
|
-
k = m.local_key_field
|
382
|
+
k = m.local_key_field
|
404
383
|
query = "select distinct #{k} from #{t}"
|
405
384
|
rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
406
385
|
local_ids = rows.collect{ |row| row[k] }
|
407
|
-
ids_to_remove = local_ids - ids
|
386
|
+
ids_to_remove = local_ids - ids
|
408
387
|
self.log("- Found #{ids_to_remove.count} #{class_type} records in the local database that are not in the remote database.")
|
409
388
|
self.log("- Deleting #{class_type} records in the local database that shouldn't be there...")
|
410
389
|
query = ["delete from #{t} where #{k} in (?)", ids_to_remove]
|
411
390
|
ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
412
|
-
|
391
|
+
|
413
392
|
# Find any ids in the remote database that should be in the local database
|
414
393
|
self.log("- Finding #{class_type} records in the remote database that should be in the local database...")
|
415
394
|
query = "select distinct #{k} from #{t}"
|
@@ -421,21 +400,15 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
421
400
|
ids_to_add.each do |id|
|
422
401
|
self.log("- Importing #{id}...")
|
423
402
|
case class_type
|
424
|
-
when
|
425
|
-
when
|
426
|
-
when
|
427
|
-
when
|
428
|
-
when 'OFF' then self.delay(:queue => 'rets').import_office(id, false)
|
429
|
-
when 'AGT' then self.delay(:queue => 'rets').import_agent(id, false)
|
430
|
-
when 'OPH' then self.delay(:queue => 'rets').import_open_house(id, false)
|
431
|
-
when 'GFX' then self.delay(:queue => 'rets').import_media(id, false)
|
403
|
+
when "Listing" then self.delay(:queue => 'rets').import_properties(id, false)
|
404
|
+
when "Office" then self.delay(:queue => 'rets').import_office(id, false)
|
405
|
+
when "Agent" then self.delay(:queue => 'rets').import_agent(id, false)
|
406
|
+
when "OpenHouse" then self.delay(:queue => 'rets').import_open_house(id, false)
|
432
407
|
end
|
433
408
|
end
|
434
|
-
|
435
409
|
end
|
436
|
-
|
437
410
|
end
|
438
|
-
|
411
|
+
|
439
412
|
def self.get_media_urls
|
440
413
|
m = self.meta(class_type)
|
441
414
|
|
@@ -443,11 +416,11 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
443
416
|
params = {
|
444
417
|
:search_type => m.search_type,
|
445
418
|
:class => class_type,
|
446
|
-
:query => "(#{m.
|
419
|
+
:query => "(#{m.matrix_modified_dt}=#{date_modified}T00:00:01+)",
|
447
420
|
:standard_names_only => true,
|
448
421
|
:timeout => -1
|
449
422
|
}
|
450
|
-
self.client.search(params.merge({ :
|
423
|
+
self.client.search(params.merge({ :count => 1 }))
|
451
424
|
count = self.client.rets_data[:code] == "20201" ? 0 : self.client.rets_data[:count]
|
452
425
|
batch_count = (count.to_f/5000.0).ceil
|
453
426
|
|
@@ -455,16 +428,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
455
428
|
k = m.remote_key_field
|
456
429
|
(0...batch_count).each do |i|
|
457
430
|
self.client.search(params.merge({ :select => [k], :limit => 5000, :offset => 5000*i })) do |data|
|
458
|
-
ids <<
|
459
|
-
when 'RES' then data[k]
|
460
|
-
when 'COM' then data[k]
|
461
|
-
when 'LND' then data[k]
|
462
|
-
when 'MUL' then data[k]
|
463
|
-
when 'OFF' then data[k]
|
464
|
-
when 'AGT' then data[k]
|
465
|
-
when 'OPH' then data[k].to_i
|
466
|
-
when 'GFX' then data[k]
|
467
|
-
end
|
431
|
+
ids << data[k]
|
468
432
|
end
|
469
433
|
end
|
470
434
|
|
@@ -474,23 +438,19 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
474
438
|
k = m.local_key_field
|
475
439
|
query = ["delete from #{t} where #{k} not in (?)", ids]
|
476
440
|
ActiveRecord::Base.connection.execute(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
477
|
-
|
441
|
+
|
478
442
|
# Find any ids in the remote database that should be in the local database
|
479
|
-
query = "select distinct #{k} from #{t}"
|
443
|
+
query = "select distinct #{k} from #{t}"
|
480
444
|
rows = ActiveRecord::Base.connection.select_all(ActiveRecord::Base.send(:sanitize_sql_array, query))
|
481
445
|
local_ids = rows.collect{ |row| row[k] }
|
482
446
|
ids_to_add = ids - local_ids
|
483
447
|
ids_to_add.each do |id|
|
484
448
|
self.log("Importing #{id}...")
|
485
449
|
case class_type
|
486
|
-
when
|
487
|
-
when
|
488
|
-
when
|
489
|
-
when
|
490
|
-
when 'OFF' then self.delay(:queue => 'rets').import_office(id, false)
|
491
|
-
when 'AGT' then self.delay(:queue => 'rets').import_agent(id, false)
|
492
|
-
when 'OPH' then self.delay(:queue => 'rets').import_open_house(id, false)
|
493
|
-
when 'GFX' then self.delay(:queue => 'rets').import_media(id)
|
450
|
+
when "Listing" then self.delay(:queue => 'rets').import_properties(id, false)
|
451
|
+
when "Office" then self.delay(:queue => 'rets').import_office(id, false)
|
452
|
+
when "Agent" then self.delay(:queue => 'rets').import_agent(id, false)
|
453
|
+
when "OpenHouse" then self.delay(:queue => 'rets').import_open_house(id, false)
|
494
454
|
end
|
495
455
|
end
|
496
456
|
end
|
@@ -501,13 +461,13 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
501
461
|
# Logging
|
502
462
|
#=============================================================================
|
503
463
|
|
504
|
-
def self.log(msg)
|
505
|
-
puts "[rets_importer] #{msg}"
|
464
|
+
def self.log(msg)
|
465
|
+
puts "[rets_importer] #{msg}"
|
506
466
|
#Rails.logger.info("[rets_importer] #{msg}")
|
507
467
|
end
|
508
|
-
|
468
|
+
|
509
469
|
def self.log2(msg)
|
510
|
-
puts "======================================================================"
|
470
|
+
puts "======================================================================"
|
511
471
|
puts "[rets_importer] #{msg}"
|
512
472
|
puts "======================================================================"
|
513
473
|
#Rails.logger.info("[rets_importer] #{msg}")
|
@@ -518,7 +478,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
518
478
|
#=============================================================================
|
519
479
|
|
520
480
|
def self.update_rets
|
521
|
-
self.log2("Updating rets...")
|
481
|
+
self.log2("Updating rets...")
|
522
482
|
if self.task_is_locked
|
523
483
|
self.log2("Task is locked, aborting.")
|
524
484
|
return
|
@@ -527,20 +487,20 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
527
487
|
task_started = self.lock_task
|
528
488
|
|
529
489
|
begin
|
530
|
-
overlap = 30.seconds
|
490
|
+
overlap = 30.seconds
|
531
491
|
if (DateTime.now - self.last_purged).to_i >= 1
|
532
492
|
self.purge
|
533
493
|
self.save_last_purged(task_started)
|
534
494
|
# Keep this in here to make sure all updates are caught
|
535
495
|
#overlap = 1.month
|
536
496
|
end
|
537
|
-
|
497
|
+
|
538
498
|
self.log2("Updating after #{self.last_updated.strftime("%FT%T%:z")}...")
|
539
499
|
self.update_after(self.last_updated - overlap)
|
540
|
-
|
500
|
+
|
541
501
|
self.log2("Saving the timestamp for when we updated...")
|
542
502
|
self.save_last_updated(task_started)
|
543
|
-
|
503
|
+
|
544
504
|
self.log2("Unlocking the task...")
|
545
505
|
self.unlock_task
|
546
506
|
rescue Exception => err
|
@@ -549,16 +509,16 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
549
509
|
ensure
|
550
510
|
self.log2("Unlocking task if last updated...")
|
551
511
|
self.unlock_task_if_last_updated(task_started)
|
552
|
-
|
512
|
+
end
|
553
513
|
|
554
514
|
# Start the same update process in five minutes
|
555
515
|
self.log2("Adding the update rets task for 5 minutes from now...")
|
556
516
|
q = "handler like '%update_rets%'"
|
557
|
-
count = Delayed::Job.where(q).count
|
517
|
+
count = Delayed::Job.where(q).count
|
558
518
|
if count == 0 || (count == 1 && Delayed::Job.where(q).first.locked_at)
|
559
519
|
self.delay(:run_at => 5.minutes.from_now, :queue => 'rets').update_rets
|
560
520
|
end
|
561
|
-
|
521
|
+
end
|
562
522
|
|
563
523
|
def self.last_updated
|
564
524
|
if !Caboose::Setting.exists?(:name => 'rets_last_updated')
|
@@ -577,7 +537,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
577
537
|
end
|
578
538
|
|
579
539
|
def self.save_last_updated(d)
|
580
|
-
s = Caboose::Setting.where(:name => 'rets_last_updated').first
|
540
|
+
s = Caboose::Setting.where(:name => 'rets_last_updated').first
|
581
541
|
s.value = d.in_time_zone(CabooseRets::timezone).strftime("%FT%T%:z")
|
582
542
|
s.save
|
583
543
|
end
|
@@ -592,7 +552,7 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
592
552
|
return Caboose::Setting.exists?(:name => 'rets_update_running')
|
593
553
|
end
|
594
554
|
|
595
|
-
def self.lock_task
|
555
|
+
def self.lock_task
|
596
556
|
d = DateTime.now.utc.in_time_zone(CabooseRets::timezone)
|
597
557
|
Caboose::Setting.create(:name => 'rets_update_running', :value => d.strftime("%FT%T%:z"))
|
598
558
|
return d
|
@@ -607,4 +567,4 @@ class CabooseRets::RetsImporter # < ActiveRecord::Base
|
|
607
567
|
self.unlock_task if setting && d.in_time_zone.strftime("%FT%T%:z") == setting.value
|
608
568
|
end
|
609
569
|
|
610
|
-
end
|
570
|
+
end
|