peddler 4.2.0 → 4.3.0
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 +4 -4
- data/README.md +116 -293
- data/lib/peddler/apis/catalog_items_v0.rb +0 -62
- data/lib/peddler/apis/seller_wallet_2024_03_01.rb +195 -0
- data/lib/peddler/parsers/openapi_parser_generator.rb +550 -0
- data/lib/peddler/parsers/smart_parser.rb +199 -0
- data/lib/peddler/version.rb +1 -1
- data/lib/peddler.rb +1 -0
- metadata +6 -3
@@ -0,0 +1,199 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "date"
|
4
|
+
require "json"
|
5
|
+
require "bigdecimal"
|
6
|
+
|
7
|
+
begin
|
8
|
+
require "money"
|
9
|
+
MONEY_GEM_AVAILABLE = true
|
10
|
+
|
11
|
+
# Configure Money to avoid issues
|
12
|
+
Money.rounding_mode = BigDecimal::ROUND_HALF_UP
|
13
|
+
|
14
|
+
# Avoid locale issues by using currency backend
|
15
|
+
if Money.respond_to?(:locale_backend=)
|
16
|
+
Money.locale_backend = :currency
|
17
|
+
end
|
18
|
+
rescue LoadError
|
19
|
+
MONEY_GEM_AVAILABLE = false
|
20
|
+
end
|
21
|
+
|
22
|
+
module Peddler
|
23
|
+
module Parsers
|
24
|
+
# Smartly parses common Amazon data types in API responses
|
25
|
+
class SmartParser
|
26
|
+
# Initialize the parser with options
|
27
|
+
#
|
28
|
+
# @param [Hash] options Parser configuration options
|
29
|
+
# @option options [Boolean] :parse_money Whether to parse money objects (default: true)
|
30
|
+
# @option options [Boolean] :parse_dates Whether to parse date/time strings (default: true)
|
31
|
+
# @option options [Boolean] :parse_dimensions Whether to parse dimension objects (default: true)
|
32
|
+
# @option options [Boolean] :symbolize_keys Whether to symbolize hash keys (default: false)
|
33
|
+
def initialize(options = {})
|
34
|
+
@parse_money = options.fetch(:parse_money, true)
|
35
|
+
@parse_dates = options.fetch(:parse_dates, true)
|
36
|
+
@parse_dimensions = options.fetch(:parse_dimensions, true)
|
37
|
+
@symbolize_keys = options.fetch(:symbolize_keys, false)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Parse the HTTP response
|
41
|
+
#
|
42
|
+
# @param [HTTP::Response] response The HTTP response
|
43
|
+
# @return [Hash] The parsed response with transformed values
|
44
|
+
def call(response)
|
45
|
+
parsed = JSON.parse(response.body.to_s)
|
46
|
+
transform_values(parsed)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Convert the response to a hash
|
50
|
+
#
|
51
|
+
# @return [Hash] The parsed response hash
|
52
|
+
def to_h
|
53
|
+
@parsed_response
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Transform values in the parsed response recursively
|
59
|
+
#
|
60
|
+
# @param [Hash, Array, Object] obj The object to transform
|
61
|
+
# @return [Hash, Array, Object] The transformed object
|
62
|
+
def transform_values(obj)
|
63
|
+
case obj
|
64
|
+
when Hash
|
65
|
+
transform_hash(obj)
|
66
|
+
when Array
|
67
|
+
obj.map { |item| transform_values(item) }
|
68
|
+
else
|
69
|
+
obj
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Transform a hash's values and possibly its keys
|
74
|
+
#
|
75
|
+
# @param [Hash] hash The hash to transform
|
76
|
+
# @return [Hash] The transformed hash
|
77
|
+
def transform_hash(hash)
|
78
|
+
result = @symbolize_keys ? {} : hash.class.new
|
79
|
+
|
80
|
+
hash.each do |k, v|
|
81
|
+
key = @symbolize_keys ? k.to_sym : k
|
82
|
+
|
83
|
+
# Apply transformations based on key patterns and value structure
|
84
|
+
transformed_value = apply_transformations(k, v)
|
85
|
+
|
86
|
+
result[key] = transformed_value
|
87
|
+
end
|
88
|
+
|
89
|
+
@parsed_response = result
|
90
|
+
end
|
91
|
+
|
92
|
+
# Apply type-specific transformations based on key and value
|
93
|
+
#
|
94
|
+
# @param [String] key The hash key
|
95
|
+
# @param [Object] value The value to transform
|
96
|
+
# @return [Object] The transformed value
|
97
|
+
def apply_transformations(key, value)
|
98
|
+
if value.is_a?(String) && @parse_dates && date_object?(key, value)
|
99
|
+
transform_date(value)
|
100
|
+
elsif value.is_a?(Hash)
|
101
|
+
if @parse_money && money_object?(value)
|
102
|
+
transform_money(value)
|
103
|
+
elsif @parse_dimensions && dimension_object?(value)
|
104
|
+
transform_dimension(value)
|
105
|
+
else
|
106
|
+
transform_values(value)
|
107
|
+
end
|
108
|
+
else
|
109
|
+
transform_values(value)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Check if a hash represents a money object
|
114
|
+
#
|
115
|
+
# @param [Hash] hash The hash to check
|
116
|
+
# @return [Boolean] True if the hash represents a money object
|
117
|
+
def money_object?(hash)
|
118
|
+
hash.size == 2 &&
|
119
|
+
hash.key?("CurrencyCode") &&
|
120
|
+
hash.key?("Amount")
|
121
|
+
end
|
122
|
+
|
123
|
+
# Transform a money object into a Money object or hash
|
124
|
+
#
|
125
|
+
# @param [Hash] money_hash The money hash to transform
|
126
|
+
# @return [Money, Hash] A Money object if gem is available, otherwise a transformed hash
|
127
|
+
def transform_money(money_hash)
|
128
|
+
currency_code = money_hash["CurrencyCode"]
|
129
|
+
amount_str = money_hash["Amount"]
|
130
|
+
|
131
|
+
if defined?(Money) && MONEY_GEM_AVAILABLE
|
132
|
+
# Convert to cents (Money uses cents as its base unit)
|
133
|
+
amount_cents = (BigDecimal(amount_str) * 100).to_i
|
134
|
+
|
135
|
+
# Create Money object with the specified currency
|
136
|
+
Money.new(amount_cents, currency_code)
|
137
|
+
else
|
138
|
+
# Fallback when Money gem not available
|
139
|
+
amount = BigDecimal(amount_str)
|
140
|
+
if @symbolize_keys
|
141
|
+
{ currency: currency_code, amount: amount }
|
142
|
+
else
|
143
|
+
{ "currency" => currency_code, "amount" => amount }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Check if a key or value suggests a date/time object
|
149
|
+
#
|
150
|
+
# @param [String] key The hash key
|
151
|
+
# @param [Object] value The value to check
|
152
|
+
# @return [Boolean] True if the value represents a date/time
|
153
|
+
def date_object?(key, value)
|
154
|
+
return false unless value.is_a?(String)
|
155
|
+
|
156
|
+
key.end_with?("Date", "Time", "At") &&
|
157
|
+
value.match?(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Transform a date string into a DateTime object
|
161
|
+
#
|
162
|
+
# @param [String] date_string The date string to transform
|
163
|
+
# @return [DateTime] A DateTime object
|
164
|
+
def transform_date(date_string)
|
165
|
+
# We intentionally use DateTime here for consistent API and testing
|
166
|
+
# even though RuboCop recommends Time
|
167
|
+
DateTime.parse(date_string)
|
168
|
+
end
|
169
|
+
|
170
|
+
# Check if a hash represents a dimension object
|
171
|
+
#
|
172
|
+
# @param [Hash] hash The hash to check
|
173
|
+
# @return [Boolean] True if the hash represents a dimension object
|
174
|
+
def dimension_object?(hash)
|
175
|
+
hash.size == 2 &&
|
176
|
+
hash.key?("Value") &&
|
177
|
+
hash.key?("Unit")
|
178
|
+
end
|
179
|
+
|
180
|
+
# Transform a dimension object into a more usable format
|
181
|
+
#
|
182
|
+
# @param [Hash] dimension_hash The dimension hash to transform
|
183
|
+
# @return [Hash] A transformed dimension object
|
184
|
+
def transform_dimension(dimension_hash)
|
185
|
+
if @symbolize_keys
|
186
|
+
{
|
187
|
+
value: dimension_hash["Value"].to_f,
|
188
|
+
unit: dimension_hash["Unit"],
|
189
|
+
}
|
190
|
+
else
|
191
|
+
{
|
192
|
+
"value" => dimension_hash["Value"].to_f,
|
193
|
+
"unit" => dimension_hash["Unit"],
|
194
|
+
}
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
data/lib/peddler/version.rb
CHANGED
data/lib/peddler.rb
CHANGED
@@ -33,6 +33,7 @@ require "peddler/apis/product_type_definitions_2020_09_01"
|
|
33
33
|
require "peddler/apis/replenishment_2022_11_07"
|
34
34
|
require "peddler/apis/reports_2021_06_30"
|
35
35
|
require "peddler/apis/sales_v1"
|
36
|
+
require "peddler/apis/seller_wallet_2024_03_01"
|
36
37
|
require "peddler/apis/sellers_v1"
|
37
38
|
require "peddler/apis/services_v1"
|
38
39
|
require "peddler/apis/shipment_invoicing_v0"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peddler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hakan Ensari
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: http
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- lib/peddler/apis/replenishment_2022_11_07.rb
|
73
73
|
- lib/peddler/apis/reports_2021_06_30.rb
|
74
74
|
- lib/peddler/apis/sales_v1.rb
|
75
|
+
- lib/peddler/apis/seller_wallet_2024_03_01.rb
|
75
76
|
- lib/peddler/apis/sellers_v1.rb
|
76
77
|
- lib/peddler/apis/services_v1.rb
|
77
78
|
- lib/peddler/apis/shipment_invoicing_v0.rb
|
@@ -99,6 +100,8 @@ files:
|
|
99
100
|
- lib/peddler/error.rb
|
100
101
|
- lib/peddler/helpers/feeds_2021_06_30.rb
|
101
102
|
- lib/peddler/marketplace.rb
|
103
|
+
- lib/peddler/parsers/openapi_parser_generator.rb
|
104
|
+
- lib/peddler/parsers/smart_parser.rb
|
102
105
|
- lib/peddler/response.rb
|
103
106
|
- lib/peddler/token.rb
|
104
107
|
- lib/peddler/version.rb
|
@@ -121,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
124
|
- !ruby/object:Gem::Version
|
122
125
|
version: '0'
|
123
126
|
requirements: []
|
124
|
-
rubygems_version: 3.6.
|
127
|
+
rubygems_version: 3.6.7
|
125
128
|
specification_version: 4
|
126
129
|
summary: Amazon Selling Partner API (SP-API) in Ruby
|
127
130
|
test_files: []
|