realogy 0.6.1 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12d8e93945c23e56e01fbe630bec8fdbe5ce249bd3b005a86d4a6912d9784db4
4
- data.tar.gz: 4d10e4f50b4966dc5c9ba7f3b520db7d521f9406799822bd80cf9f422c4589a5
3
+ metadata.gz: 8bd21ebae2bdd067d907b8be8b4205f91874e8074f83189bcb719d793e251672
4
+ data.tar.gz: a9afc5328a86797ec677fd28aaaf1d1932bc29cf65a84e906b956c9d7ac76897
5
5
  SHA512:
6
- metadata.gz: bd20fd303e29928de9b4f087dca56ccaf4c42934bb17d1e71439bf343b02add61d9c449a0fa94b9bfe6fc959273006bb987cdcd7381dc7542134b844fef18a6b
7
- data.tar.gz: ba898e4b69cd3db029e63db391117a337f10d66a2770a7ba932eb85885f44d8708c6c5dc2474688fef4cfed5123f388fa676675ed6ad67098ed5d6020074b94f
6
+ metadata.gz: fb23e4584877fb4a473f05ee86d68a7a325adde0a7941a43f643d18b94238522673188f0d2adb8f80b332b2eb02614d97503c0404d9239072ec4247eff9b90de
7
+ data.tar.gz: 79329f73bdcc2f6467b46246e105bad993ee24bc335d3bd64e0fdd2001cc8cedb309a2949ef26be20ad7badd6b024ff1c22f5f25c8136ff09f7695ca1c39bc7b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- realogy (0.5.9)
4
+ realogy (0.6.3)
5
5
  activerecord (>= 5.0)
6
6
  oauth2
7
7
 
data/README.md CHANGED
@@ -128,9 +128,10 @@ config.active_job.queue_adapter = :delayed_job
128
128
  ```ruby
129
129
  realogy = Realogy::DataSync.client
130
130
  ```
131
- #### Retrieve array of objects
132
131
 
133
- The calls to retrieve entities are:
132
+ #### Get active objects
133
+
134
+ The calls to retrieve active entities are:
134
135
 
135
136
  ```ruby
136
137
  realogy.get_active_agents
@@ -140,20 +141,31 @@ realogy.get_active_offices
140
141
  realogy.get_active_teams
141
142
  ```
142
143
 
143
- When no argument is submitted, all entities are returned. Filters can be applied for `brandCode` or `countryCode` though, provided as keys in a hash. For example:
144
+ When no argument is submitted, all active entities are returned.
145
+
146
+ Filters can be applied for `brandCode` and `countryCode`. For example:
144
147
 
145
148
  ```ruby
146
149
  # Fetch all active agents, for all brands, in all countries:
147
- realogy.get_active_agents()
150
+ realogy.get_active_agents
148
151
 
149
152
  # Fetch all active agents, for all brands, in Sweden:
150
- realogy.get_active_agents({countryCode: "SE"})
153
+ realogy.get_active_companies(countryCode: "SE")
151
154
 
155
+ # Allowed brandCode values: C21, CB, ERA, SIR, BHG, CBC, ZIP, CLB, & COR
152
156
  # Fetch all active Sotheby's agents in all countries:
153
- realogy.get_active_agents({brandCode: "SIR"})
157
+ realogy.get_active_offices(brandCode: "SIR")
154
158
 
155
159
  # Fetch all active Sotheby's agents in Sweden:
156
- realogy.get_active_agents({brandCode: "SIR", countryCode: "SE"})
160
+ realogy.get_active_teams(brandCode: "SIR", countryCode: "SE")
161
+ ```
162
+
163
+ When fetching listings, the type of listing can also be specified:
164
+
165
+ ```ruby
166
+ # Allowed type values: ForSale, ForRent, ForSaleCommercial, & ForLeaseCommercial
167
+ # Fetch all active agents, for all brands, in all countries:
168
+ realogy.get_active_listings(type: "ForSale")
157
169
  ```
158
170
 
159
171
  #### Retrieve delta of objects
@@ -170,16 +182,77 @@ realogy.get_teams_delta
170
182
 
171
183
  Each hash in the returned arrays includes a key `action` that returns either `Delete` or `Upsert` to indicate if the object has been deleted or created/updated.
172
184
 
173
- When no argument is passed, the delta returned is for the last 15 minutes. A custom minutes delta can be passed in:
185
+ When no argument is passed, the delta returned is for the last 20 minutes. A custom minutes delta can be passed in:
186
+
187
+ ```ruby
188
+ realogy.get_agents_delta(since: 20.minutes.ago) # 20 minutes is the default
189
+ realogy.get_companies_delta(since: 1.hour.ago)
190
+ realogy.get_listings_delta(since: 2.hours.ago)
191
+ realogy.get_offices_delta(since: 5.minutes.ago)
192
+ realogy.get_teams_delta(since: 1.day.ago)
193
+ ```
194
+
195
+ A few additional parameters are allowed:
196
+
197
+ ```ruby
198
+ realogy.get_listings_delta(brandCode: "SIR")
199
+ realogy.get_listings_delta(companyIds: "12345")
200
+ realogy.get_listings_delta(companyIds: "12345, 23456, 34567")
201
+ realogy.get_listings_delta(countryCode: "IT")
202
+ realogy.get_listings_delta(limit: 10)
203
+ realogy.get_listings_delta(type: "ForSale")
204
+ ```
205
+
206
+ In case there are more entities available than is returned by the initial call, there will be a `nextLink` value present in the JSON response. By calling the `nextLink` URL as long as it is present, you will make retrieve all results.
207
+
208
+ If you want to automatically return all entities, pass in the flag `followNext: true` in your call:
209
+
210
+ ```ruby
211
+ realogy.get_listings_delta( ... , followNext: true)
212
+ ```
213
+
214
+ When passing in `followNext: true`, the returned result will be an array of entities rather than the JSON object returned if it is omitted.
215
+
216
+
217
+ #### Get all listings
218
+
219
+ To retrieve all listings, `fromDate` and `brandCode` are mandatory parameters. A minimum call to retrieve all listing entities could look like this:
220
+
221
+ ```ruby
222
+ realogy.get_all_listings(brandCode: "COR", fromDate: 1.week.ago.to_query_string)
223
+ ```
224
+
225
+ These are additional filters that can be applied:
226
+
227
+ ```ruby
228
+ # fromDate and toDate must be converted to supported text format. This is done with to_query_string:
229
+ realogy.get_all_listings(brandCode: "COR", fromDate: 1.week.ago.to_query_string, toDate: DateTime.now.to_query_string)
230
+
231
+ # Allowed type values: ForSale, ForRent, ForSaleCommercial, & ForLeaseCommercial
232
+ realogy.get_all_listings(brandCode: "C21", fromDate: 1.week.ago.to_query_string, type: "ForSale")
233
+
234
+ # Allowed status values: Active, Available, Pending, & Closed
235
+ realogy.get_all_listings(brandCode: "CB", fromDate: 1.week.ago.to_query_string, status: "Active")
236
+
237
+ # Limit results to a particular country
238
+ realogy.get_all_listings(brandCode: "SIR", fromDate: 1.week.ago.to_query_string, countryCode: "IT")
239
+
240
+ # Limit number of listings per result batch. Allowed span: 10–1000.
241
+ realogy.get_all_listings(brandCode: "BHG", fromDate: 1.week.ago.to_query_string, limit: 10)
242
+
243
+ ```
244
+
245
+ In case there are more listings available than is returned by the `get_all_listings` call, there will be a `nextLink` value present in the JSON response. By calling the `nextLink` URL as long as it is present, you will traverse through all results.
246
+
247
+ If you want to automatically return all results, pass in the flag `followNext: true` in your call:
174
248
 
175
249
  ```ruby
176
- realogy.get_agents_delta({since: 15.minutes.ago}) # 15 minutes is the default
177
- realogy.get_companies_delta({since: 1.hour.ago})
178
- realogy.get_listings_delta({since: 2.hours.ago})
179
- realogy.get_offices_delta({since: 5.minutes.ago})
180
- realogy.get_teams_delta({since: 1.day.ago})
250
+ realogy.get_all_listings( ... , followNext: true)
181
251
  ```
182
252
 
253
+ When passing in `followNext: true`, the returned result will be an array of entities rather than the JSON object returned if it is omitted.
254
+
255
+
183
256
  #### Retrieve JSON object
184
257
 
185
258
  ```ruby
@@ -23,6 +23,10 @@ module Realogy
23
23
  get_active_teams: "teams/active"
24
24
  }
25
25
 
26
+ ALL_API_ENDPOINTS = {
27
+ get_all_listings: "listings/all"
28
+ }
29
+
26
30
  DELTA_API_ENDPOINTS = {
27
31
  get_agents_delta: "agents/delta",
28
32
  get_companies_delta: "companies/delta",
@@ -47,25 +51,69 @@ module Realogy
47
51
  endpoint = ACTIVE_API_ENDPOINTS[method_name]
48
52
  params = {
49
53
  'brandCode': hash[:brandCode],
50
- 'countryCode': hash[:countryCode]
54
+ 'countryCode': hash[:countryCode],
55
+ 'type': hash[:type]
51
56
  }.compact
52
57
  return perform_api_call(endpoint, params)
53
58
  end
54
59
  end
55
60
 
61
+ ALL_API_ENDPOINTS.keys.each do |method_name|
62
+ define_method method_name do |*args|
63
+ hash = args.first.is_a?(::Hash) ? args.first : {}
64
+ endpoint = ALL_API_ENDPOINTS[method_name]
65
+ params = {
66
+ 'brandCode': hash[:brandCode],
67
+ 'countryCode': hash[:countryCode],
68
+ 'cursor': hash[:cursor],
69
+ 'fromDate': hash[:fromDate],
70
+ 'limit': hash[:limit],
71
+ 'status': hash[:status],
72
+ 'toDate': hash[:toDate],
73
+ 'type': hash[:type],
74
+ 'followNext': hash[:followNext]
75
+ }.compact
76
+ if hash[:followNext]
77
+ entities = []
78
+ response = perform_api_call(endpoint, params)
79
+ entities << response["data"]
80
+ while response["nextLink"].present?
81
+ response = perform_simple_call(response["nextLink"])
82
+ entities << response["data"]
83
+ end
84
+ return entities.flatten
85
+ else
86
+ return perform_api_call(endpoint, params)
87
+ end
88
+ end
89
+ end
90
+
56
91
  DELTA_API_ENDPOINTS.keys.each do |method_name|
57
92
  define_method method_name do |*args|
58
- entities = []
59
- hash = args.first.is_a?(::Hash) ? args.first : {since: 15.minutes.ago}
60
- params = {'since': JSON[hash[:since].to_json]}
93
+ hash = args.first.is_a?(::Hash) ? args.first : {}
94
+ hash[:since] = JSON(20.minutes.ago.to_json) if hash[:since].blank?
61
95
  endpoint = DELTA_API_ENDPOINTS[method_name]
62
- response = perform_api_call(endpoint, params)
63
- entities << response["data"]
64
- while response["nextLink"].present?
65
- response = perform_simple_call(response["nextLink"])
96
+ params = {
97
+ 'since': JSON[hash[:since].to_json],
98
+ 'brandCode': hash[:brandCode],
99
+ 'companyIds': hash[:companyIds].to_s.split(',').map(&:strip),
100
+ 'countryCode': hash[:countryCode],
101
+ 'limit': hash[:limit],
102
+ 'type': hash[:type],
103
+ 'followNext': hash[:followNext]
104
+ }.compact
105
+ if hash[:followNext]
106
+ entities = []
107
+ response = perform_api_call(endpoint, params)
66
108
  entities << response["data"]
109
+ while response["nextLink"].present?
110
+ response = perform_simple_call(response["nextLink"])
111
+ entities << response["data"]
112
+ end
113
+ return entities.flatten
114
+ else
115
+ return perform_api_call(endpoint, params)
67
116
  end
68
- return entities.flatten
69
117
  end
70
118
  end
71
119
 
@@ -128,14 +176,18 @@ module Realogy
128
176
  return client.client_credentials.get_token(scope: scope)
129
177
  end
130
178
 
179
+ def oauth2_token_path
180
+ return File.join(Dir.tmpdir, [Rails.application.credentials.dig(:realogy, :client_id).parameterize, "-oauth-token.json"].join)
181
+ end
182
+
131
183
  def oauth2_client_credentials_token(client_id, client_secret, token_url, scope)
132
- @token = OAuth2::AccessToken.read_token_from_file(".oauth-access-token.json")
184
+ @token = OAuth2::AccessToken.read_token_from_file(oauth2_token_path)
133
185
  expiry = @token.try(:expires_at).present? ? DateTime.strptime(@token.expires_at.to_s, '%s') : 1.day.ago
134
186
  if expiry > DateTime.now.utc
135
187
  return @token.token
136
188
  else
137
189
  @token = oauth2_client_credentials_token_object(client_id, client_secret, token_url, scope)
138
- @token.save_token_to_file(".oauth-access-token.json")
190
+ @token.save_token_to_file(oauth2_token_path)
139
191
  return @token.token
140
192
  end
141
193
  end
@@ -0,0 +1,11 @@
1
+ DateTime.class_eval do
2
+ def to_query_string
3
+ self.to_json.split("\"").last
4
+ end
5
+ end
6
+
7
+ ActiveSupport::TimeWithZone.class_eval do
8
+ def to_query_string
9
+ self.to_datetime.to_json.split("\"").last
10
+ end
11
+ end
@@ -108,31 +108,31 @@ namespace :realogy do
108
108
 
109
109
  desc "Delta update for Agents. Optionally provide delta in minutes."
110
110
  task :sync_agents_delta, [:since_minutes] => [:environment] do |t, args|
111
- args.with_defaults(since_minutes: 15)
111
+ args.with_defaults(since_minutes: 20)
112
112
  perform_delta_update_for Realogy::Agent, args[:since_minutes]
113
113
  end
114
114
 
115
115
  desc "Delta update for Companies. Optionally provide delta in minutes."
116
116
  task :sync_companies_delta, [:since_minutes] => [:environment] do |t, args|
117
- args.with_defaults(since_minutes: 15)
117
+ args.with_defaults(since_minutes: 20)
118
118
  perform_delta_update_for Realogy::Company, args[:since_minutes]
119
119
  end
120
120
 
121
121
  desc "Delta update for Listings. Optionally provide delta in minutes."
122
122
  task :sync_listings_delta, [:since_minutes] => [:environment] do |t, args|
123
- args.with_defaults(since_minutes: 15)
123
+ args.with_defaults(since_minutes: 20)
124
124
  perform_delta_update_for Realogy::Listing, args[:since_minutes]
125
125
  end
126
126
 
127
127
  desc "Delta update for Offices. Optionally provide delta in minutes."
128
128
  task :sync_offices_delta, [:since_minutes] => [:environment] do |t, args|
129
- args.with_defaults(since_minutes: 15)
129
+ args.with_defaults(since_minutes: 20)
130
130
  perform_delta_update_for Realogy::Office, args[:since_minutes]
131
131
  end
132
132
 
133
133
  desc "Delta update for Teams. Optionally provide delta in minutes."
134
134
  task :sync_teams_delta, [:since_minutes] => [:environment] do |t, args|
135
- args.with_defaults(since_minutes: 15)
135
+ args.with_defaults(since_minutes: 20)
136
136
  perform_delta_update_for Realogy::Team, args[:since_minutes]
137
137
  end
138
138
 
@@ -1,3 +1,3 @@
1
1
  module Realogy
2
- VERSION = "0.6.1"
2
+ VERSION = "0.6.4"
3
3
  end
data/lib/realogy.rb CHANGED
@@ -2,6 +2,7 @@ require "realogy/version"
2
2
  require "realogy/railtie" if defined?(Rails)
3
3
  require "realogy/app/models/application_record.rb"
4
4
  require "realogy/app/models/data_sync.rb"
5
+ require "realogy/app/models/date_time.rb"
5
6
  require "realogy/app/models/hash.rb"
6
7
  require "realogy/app/models/realogy/entity.rb"
7
8
  require "realogy/app/models/realogy/agent.rb"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: realogy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Edlund
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-14 00:00:00.000000000 Z
11
+ date: 2022-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -120,6 +120,7 @@ files:
120
120
  - lib/realogy/app/jobs/populate_realogy_entity_job.rb
121
121
  - lib/realogy/app/models/application_record.rb
122
122
  - lib/realogy/app/models/data_sync.rb
123
+ - lib/realogy/app/models/date_time.rb
123
124
  - lib/realogy/app/models/hash.rb
124
125
  - lib/realogy/app/models/realogy/agent.rb
125
126
  - lib/realogy/app/models/realogy/company.rb