amplify_syndication 0.3.1 → 0.3.3

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: f0dda531062bfbbef4387181c6e46705b75254f69795cc2edb5ed7190adeb0c9
4
- data.tar.gz: fbeb9c17508bdcc30296e936912742b1ecd70baccec988008678256eec589f9c
3
+ metadata.gz: c92a66b9d1f752e01a51b3bc21f2f623c245239e893aaecbf034dcff960e43c0
4
+ data.tar.gz: efd9af0c94d48954fd160976d5195f73e65f9742d2891ac807143aff49fababe
5
5
  SHA512:
6
- metadata.gz: e6898e0c47727b6d6f6f51342a47d425adfda709943036ff9f8361375cae03787c69c02e99624773ff5242d9294bcd439d5cb9882d489e64af640ad04d715b74
7
- data.tar.gz: c8e6b5aef477525e0bfd9a9d2caba49aad4929cae0553121c471ff40ed41619965b5891cf267779a2c1dbf79016871f3727d15fcc03ee86c779c40db7997937c
6
+ metadata.gz: 0a4174eeb7a537ee9f751e19335fce2cb2dbfe18084576c86673065d2ff938070d9092555febe3c6624f0b4c584f13fa34c91443a2a1d72b753057ccd78b1784
7
+ data.tar.gz: 34fc64abfa245212dfe9851d9835e30e17894d806f2a7b0d7f9c46450f9cb08be91d2a738210dc63f7b57d8bc06f127984271ee895f884cb73ca9573118fcc7e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,51 @@
1
+ ## 0.3.2 (2025-11-19)
2
+
3
+ ### Improved
4
+ - Internal request logging now clearly displays the final AMPRE request path for easier debugging.
5
+ - Media filter logic now mirrors the stable pattern used in Property replication filters.
6
+
7
+ ### Fixed
8
+ - Corrected Media API $filter construction to comply with AMPRE OData requirements.
9
+ - Removed incorrect manual URI-encoding that caused 400 The URI is malformed errors.
10
+ - Resolved issues where HTTPClient encoding differed from curl behavior, ensuring valid query formation.
11
+ - Restored full pagination functionality for media fetching via:
12
+ - `fetch_all_media_for_resource`
13
+
14
+ ## 0.3.1 (2025-11-18)
15
+
16
+ ### Added
17
+ - Full media pagination support:
18
+ - `fetch_media_batch`
19
+ - `each_media_batch`
20
+ - `fetch_all_media_for_listing`
21
+ - Media batching now matches the Property replication architecture.
22
+ - Support for listing-level media syncs with ordered pagination (`Order asc, MediaKey`).
23
+
24
+ ### Improved
25
+ - Internal consistency updates across API helper layers.
26
+
27
+ ### Fixed
28
+ - Minor documentation improvements around Media calls.
29
+
30
+ ## 0.2.2
31
+
32
+ #### Enhancements
33
+
34
+ - Added lookup helpers:
35
+ - `fetch_lookup_batch`
36
+ - `each_lookup_batch`
37
+ - `fetch_all_lookups`
38
+ - `lookup(lookup_name, batch_size:, sleep_seconds:)`
39
+ These support optional filters and configurable sleep intervals for safer long-running syncs.
40
+
41
+ - Added replication helpers:
42
+ - `fetch_initial_download_batch`
43
+ - `each_initial_download_batch`
44
+ - Improved `perform_initial_download` and `fetch_updates` to support batch-style processing and resumable checkpoints.
45
+
46
+ - Improved internal filter construction for replication queries to better combine user-provided filters with checkpoint-based ranges.
47
+
48
+
1
49
  ## 0.1.0
2
50
 
3
51
  API Client for use with Amplify Syndication API
@@ -170,23 +170,24 @@ module AmplifySyndication
170
170
  batch_size: 100,
171
171
  fields: ["ModificationTimestamp", "ListingKey"],
172
172
  filter: nil,
173
- checkpoint: { last_timestamp: "1970-01-01T00:00:00Z", last_key: 0 }
173
+ checkpoint: { last_timestamp: "1970-01-01T00:00:00Z", last_key: "0" }
174
174
  )
175
- encoded_ts = URI.encode_www_form_component(checkpoint[:last_timestamp])
175
+ last_timestamp = checkpoint[:last_timestamp].to_s
176
+ last_key = checkpoint[:last_key].to_s.gsub("'", "''")
176
177
 
177
- # checkpoint filter: everything strictly after the last (timestamp, key) pair
178
- checkpoint_filter = "(ModificationTimestamp gt #{encoded_ts}) " \
179
- "or (ModificationTimestamp eq #{encoded_ts} and ListingKey gt '#{checkpoint[:last_key]}')"
178
+ checkpoint_filter =
179
+ "(ModificationTimestamp gt #{last_timestamp}) " \
180
+ "or (ModificationTimestamp eq #{last_timestamp} and ListingKey gt '#{last_key}')"
180
181
 
181
182
  conditions = []
182
- conditions << "(#{filter})" if filter
183
+ conditions << "(#{filter})" if filter && !filter.empty?
183
184
  conditions << "(#{checkpoint_filter})"
184
185
 
185
186
  query_options = {
186
- "$select" => fields.join(","),
187
- "$filter" => conditions.join(" and "),
187
+ "$select" => fields.join(","),
188
+ "$filter" => conditions.join(" and "),
188
189
  "$orderby" => "ModificationTimestamp,ListingKey",
189
- "$top" => batch_size
190
+ "$top" => batch_size
190
191
  }
191
192
 
192
193
  response = fetch_with_options(resource, query_options)
@@ -202,7 +203,7 @@ module AmplifySyndication
202
203
  fields: ["ModificationTimestamp", "ListingKey"],
203
204
  filter: nil,
204
205
  sleep_seconds: 10,
205
- checkpoint: { last_timestamp: "1970-01-01T00:00:00Z", last_key: 0 }
206
+ checkpoint: { last_timestamp: "1970-01-01T00:00:00Z", last_key: "0" }
206
207
  )
207
208
  loop do
208
209
  batch = fetch_initial_download_batch(
@@ -238,7 +239,7 @@ module AmplifySyndication
238
239
  fields: ["ModificationTimestamp", "ListingKey"],
239
240
  filter: nil,
240
241
  sleep_seconds: 10,
241
- checkpoint: { last_timestamp: "1970-01-01T00:00:00Z", last_key: 0 }
242
+ checkpoint: { last_timestamp: "1970-01-01T00:00:00Z", last_key: "0" }
242
243
  )
243
244
  results = []
244
245
 
@@ -268,7 +269,7 @@ module AmplifySyndication
268
269
  batch_size: 100,
269
270
  fields: ["ModificationTimestamp", "ListingKey"],
270
271
  filter: nil,
271
- checkpoint: { last_timestamp: "1970-01-01T00:00:00Z", last_key: 0 },
272
+ checkpoint: { last_timestamp: "1970-01-01T00:00:00Z", last_key: "0" },
272
273
  sleep_seconds: 10
273
274
  )
274
275
  if block_given?
@@ -326,62 +327,32 @@ module AmplifySyndication
326
327
  fetch_with_options("Media", query_options)
327
328
  end
328
329
 
329
- # Fetch media by ResourceName and ResourceRecordKey
330
- def fetch_media_by_resource(resource_name, resource_key, batch_size = 100)
331
- filter = "ResourceRecordKey eq '#{resource_key}' and ResourceName eq '#{resource_name}'"
332
-
333
- query_options = {
334
- "$filter" => filter,
335
- "$orderby" => "ModificationTimestamp,MediaKey",
336
- "$top" => batch_size
337
- }
338
-
339
- fetch_with_options("Media", query_options)
340
- end
341
-
342
- def fetch_media_batch(listing_key:, skip:, top: 100)
343
- query_options = {
344
- "$filter" => "ResourceName eq 'Property' and ResourceRecordKey eq '#{listing_key}'",
345
- "$orderby" => "Order asc, MediaKey",
346
- "$top" => top,
347
- "$skip" => skip
348
- }
349
-
350
- response = fetch_with_options("Media", query_options)
351
- response["value"] || []
352
- end
330
+ def fetch_all_media_for_resource(resource_name, resource_key, batch_size: 100, sleep_seconds: 1)
331
+ filter = "(ResourceRecordKey eq '#{resource_key}' and ResourceName eq '#{resource_name}')"
353
332
 
354
- def each_media_batch(listing_key:, batch_size: 100, sleep_seconds: 1)
333
+ results = []
355
334
  skip = 0
356
335
 
357
336
  loop do
358
- batch = fetch_media_batch(
359
- listing_key: listing_key,
360
- skip: skip,
361
- top: batch_size
362
- )
363
-
337
+ query_options = {
338
+ "$filter" => filter,
339
+ "$orderby" => "ModificationTimestamp,MediaKey",
340
+ "$top" => batch_size,
341
+ "$skip" => skip
342
+ }
343
+
344
+ response = fetch_with_options("Media", query_options)
345
+ batch = response["value"] || []
364
346
  break if batch.empty?
365
- yield(batch) if block_given?
366
-
367
- skip += batch_size
368
- sleep(sleep_seconds) if sleep_seconds.positive?
369
- end
370
- end
371
347
 
372
- def fetch_all_media_for_listing(listing_key, batch_size: 100, sleep_seconds: 1)
373
- results = []
374
-
375
- each_media_batch(
376
- listing_key: listing_key,
377
- batch_size: batch_size,
378
- sleep_seconds: sleep_seconds
379
- ) do |batch|
380
348
  results.concat(batch)
349
+
350
+ break if batch.size < batch_size
351
+ skip += batch_size
352
+ sleep(sleep_seconds)
381
353
  end
382
354
 
383
355
  results
384
356
  end
385
-
386
357
  end
387
358
  end
@@ -16,23 +16,25 @@ module AmplifySyndication
16
16
  "Authorization" => "Bearer #{@access_token}",
17
17
  "Accept" => "application/json"
18
18
  }
19
+
19
20
  response = @http_client.get(url, params, headers)
20
21
  parse_response(response)
21
22
  end
22
23
 
23
24
  def get_with_options(endpoint, options = {})
24
- query_string = options.map { |key, value| "#{key}=#{value}" }.join("&")
25
+ query_string = build_query_string(options)
25
26
  get("#{endpoint}?#{query_string}")
26
27
  end
27
28
 
28
29
  private
29
30
 
30
- # Converts a hash of query options into a URL-encoded query string
31
31
  def build_query_string(options)
32
- URI.encode_www_form(options)
32
+ options.map do |key, value|
33
+ escaped_value = URI::DEFAULT_PARSER.escape(value.to_s)
34
+ "#{key}=#{escaped_value}"
35
+ end.join("&")
33
36
  end
34
37
 
35
- # Parses JSON response, raises an error for non-200 responses
36
38
  def parse_response(response)
37
39
  if response.status == 200
38
40
  JSON.parse(response.body)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AmplifySyndication
4
- VERSION = "0.3.1"
4
+ VERSION = "0.3.3"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amplify_syndication
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen Higgins
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-11-18 00:00:00.000000000 Z
11
+ date: 2026-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient