akeneo 1.5.0 → 1.8.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/Gemfile.lock +8 -8
- data/README.md +23 -0
- data/akeneo.gemspec +2 -2
- data/lib/akeneo/api.rb +18 -18
- data/lib/akeneo/attribute_service.rb +19 -0
- data/lib/akeneo/category_service.rb +13 -0
- data/lib/akeneo/family_service.rb +13 -0
- data/lib/akeneo/product_service.rb +19 -6
- data/lib/akeneo/published_product_service.rb +1 -1
- data/lib/akeneo/service_base.rb +50 -3
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e2c55807f94475e39690f1ac2eb6782379f501a3c89e8fa6a45b8073199bd70
|
4
|
+
data.tar.gz: 332e8bf0c5ccb96d735e40bc602b48da245b0970e5dc9716c908feb8974638bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ea4ddf2d9aa56a77c05697140fdea805e349da2736ef7c8e90097eb0d6c6ae3c7e959375f0ea7df29e04abd464044ccabd4ce9dbeabef0a07e717e3fb40bab6
|
7
|
+
data.tar.gz: 0e7b75d0a365852842118be5c027ca7cbb7cb16c337feaadc0c76a137a114b29d95fd86953bef567e3a14e5c1571e275674d8351740dc6bff93391ae73bb2695
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
akeneo (1.
|
5
|
-
httparty
|
4
|
+
akeneo (1.7.1)
|
5
|
+
httparty (~> 0.17.0)
|
6
6
|
mime-types
|
7
7
|
redis
|
8
8
|
semantic_logger
|
@@ -13,18 +13,18 @@ GEM
|
|
13
13
|
addressable (2.5.2)
|
14
14
|
public_suffix (>= 2.0.2, < 4.0)
|
15
15
|
ast (2.4.0)
|
16
|
-
concurrent-ruby (1.1.
|
16
|
+
concurrent-ruby (1.1.5)
|
17
17
|
crack (0.4.3)
|
18
18
|
safe_yaml (~> 1.0.0)
|
19
19
|
diff-lcs (1.3)
|
20
20
|
hashdiff (0.3.8)
|
21
|
-
httparty (0.
|
21
|
+
httparty (0.17.0)
|
22
22
|
mime-types (~> 3.0)
|
23
23
|
multi_xml (>= 0.5.2)
|
24
24
|
jaro_winkler (1.5.2)
|
25
25
|
mime-types (3.2.2)
|
26
26
|
mime-types-data (~> 3.2015)
|
27
|
-
mime-types-data (3.
|
27
|
+
mime-types-data (3.2019.0331)
|
28
28
|
multi_xml (0.6.0)
|
29
29
|
parallel (1.12.1)
|
30
30
|
parser (2.5.3.0)
|
@@ -32,8 +32,8 @@ GEM
|
|
32
32
|
powerpack (0.1.2)
|
33
33
|
public_suffix (3.0.3)
|
34
34
|
rainbow (3.0.0)
|
35
|
-
rake (
|
36
|
-
redis (4.1.
|
35
|
+
rake (13.0.1)
|
36
|
+
redis (4.1.2)
|
37
37
|
rspec (3.8.0)
|
38
38
|
rspec-core (~> 3.8.0)
|
39
39
|
rspec-expectations (~> 3.8.0)
|
@@ -57,7 +57,7 @@ GEM
|
|
57
57
|
unicode-display_width (~> 1.4.0)
|
58
58
|
ruby-progressbar (1.10.0)
|
59
59
|
safe_yaml (1.0.4)
|
60
|
-
semantic_logger (4.
|
60
|
+
semantic_logger (4.5.0)
|
61
61
|
concurrent-ruby (~> 1.0)
|
62
62
|
unicode-display_width (1.4.1)
|
63
63
|
webmock (3.5.1)
|
data/README.md
CHANGED
@@ -19,6 +19,29 @@ client = Akeneo::API.new(
|
|
19
19
|
|
20
20
|
client.product(511707)
|
21
21
|
# => {"identifier"=>"511707", "family"=>"simple_product", "parent"=>nil, "groups"=>[]...
|
22
|
+
|
23
|
+
Some methods with parameters is inside services classes, and be called that way
|
24
|
+
client.family_service.all
|
25
|
+
# => Returns a Enumeration to list all families
|
26
|
+
|
27
|
+
client.product_service.create(object)
|
28
|
+
# => Returns a JSON with status code relative to what happened
|
29
|
+
201: CREATED
|
30
|
+
"{"line":1,"identifier":"bot","status_code":201}"
|
31
|
+
|
32
|
+
204: NO CONTENT/UPDATED
|
33
|
+
"{"line":1,"identifier":"top","status_code":204}"
|
34
|
+
|
35
|
+
422: UNPROCESSABLE ENTITY/ERROR
|
36
|
+
In this case, returns message too
|
37
|
+
"{"line":1,"identifier":"bot","status_code":422,"message":"Validation failed.","errors":[{"property":"values","message":"The value Top 2 vezes is already set on another product for the unique attribute nome_marketing","attribute":"nome_marketing","locale":null,"scope":null}]}"
|
38
|
+
```
|
39
|
+
|
40
|
+
Returns options from attribute
|
41
|
+
```
|
42
|
+
options = client.attribute_service.options(codigo_do_atributo)
|
43
|
+
|
44
|
+
options["_embedded"]["items"].map{|a| [a['code'], a['labels']]}
|
22
45
|
```
|
23
46
|
|
24
47
|
## Configuration
|
data/akeneo.gemspec
CHANGED
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = 'akeneo'
|
8
|
-
spec.version = '1.
|
8
|
+
spec.version = '1.8.0'
|
9
9
|
spec.authors = ['AWN Dev Team']
|
10
10
|
spec.email = ['edv@awn.de']
|
11
11
|
|
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_development_dependency 'rspec'
|
33
33
|
spec.add_development_dependency 'rubocop'
|
34
34
|
spec.add_development_dependency 'webmock'
|
35
|
-
spec.add_dependency 'httparty'
|
35
|
+
spec.add_dependency 'httparty', '~> 0.17.0'
|
36
36
|
spec.add_dependency 'mime-types'
|
37
37
|
spec.add_dependency 'redis'
|
38
38
|
spec.add_dependency 'semantic_logger'
|
data/lib/akeneo/api.rb
CHANGED
@@ -12,24 +12,23 @@ module Akeneo
|
|
12
12
|
|
13
13
|
def initialize(url:, client_id:, secret:, username:, password:)
|
14
14
|
@url = url
|
15
|
-
authorization_service.authorize!(
|
16
|
-
client_id: client_id,
|
17
|
-
secret: secret,
|
18
|
-
username: username,
|
19
|
-
password: password
|
20
|
-
)
|
15
|
+
authorization_service.authorize!(client_id: client_id, secret: secret, username: username, password: password)
|
21
16
|
end
|
22
17
|
|
23
18
|
def fresh_access_token
|
24
19
|
authorization_service.fresh_access_token
|
25
20
|
end
|
26
21
|
|
27
|
-
def product(
|
28
|
-
product_service.find(
|
22
|
+
def product(code)
|
23
|
+
product_service.find(code)
|
29
24
|
end
|
30
25
|
|
31
|
-
def products(with_family: nil)
|
32
|
-
product_service.all(
|
26
|
+
def products(with_family: nil, with_completeness: nil, updated_after: nil)
|
27
|
+
product_service.all(
|
28
|
+
with_family: with_family,
|
29
|
+
with_completeness: with_completeness,
|
30
|
+
updated_after: updated_after
|
31
|
+
)
|
33
32
|
end
|
34
33
|
|
35
34
|
def published_products(updated_after: nil)
|
@@ -44,6 +43,10 @@ module Akeneo
|
|
44
43
|
product_service.create_or_update(code, options)
|
45
44
|
end
|
46
45
|
|
46
|
+
def create_product(options:)
|
47
|
+
product_service.create(options)
|
48
|
+
end
|
49
|
+
|
47
50
|
def create_or_update_product_model(code:, options:)
|
48
51
|
product_model_service.create_or_update(code, options)
|
49
52
|
end
|
@@ -79,8 +82,8 @@ module Akeneo
|
|
79
82
|
product_model_service.find(product_parent['parent'])
|
80
83
|
end
|
81
84
|
|
82
|
-
def family(
|
83
|
-
family_service.find(
|
85
|
+
def family(code)
|
86
|
+
family_service.find(code)
|
84
87
|
end
|
85
88
|
|
86
89
|
def family_variant(family_code, family_variant_code)
|
@@ -91,14 +94,11 @@ module Akeneo
|
|
91
94
|
family_variant = family_service.variant(family_code, family_variant_code)
|
92
95
|
return [] unless family_variant
|
93
96
|
|
94
|
-
[
|
95
|
-
find_attribute_code_for_level(family_variant, 1),
|
96
|
-
find_attribute_code_for_level(family_variant, 2)
|
97
|
-
].compact
|
97
|
+
[find_attribute_code_for_level(family_variant, 1), find_attribute_code_for_level(family_variant, 2)].compact
|
98
98
|
end
|
99
99
|
|
100
|
-
def brothers_and_sisters(
|
101
|
-
product_service.brothers_and_sisters(
|
100
|
+
def brothers_and_sisters(code)
|
101
|
+
product_service.brothers_and_sisters(code)
|
102
102
|
end
|
103
103
|
|
104
104
|
def attribute(code)
|
@@ -4,12 +4,31 @@ require_relative './service_base.rb'
|
|
4
4
|
|
5
5
|
module Akeneo
|
6
6
|
class AttributeService < ServiceBase
|
7
|
+
def all
|
8
|
+
Enumerator.new do |attributes|
|
9
|
+
request_url = "/attributes?#{limit_param}"
|
10
|
+
|
11
|
+
loop do
|
12
|
+
response = get_request(request_url)
|
13
|
+
extract_collection_items(response).each { |attribute| attributes << attribute }
|
14
|
+
request_url = extract_next_page_path(response)
|
15
|
+
break unless request_url
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
7
20
|
def find(code)
|
8
21
|
response = get_request("/attributes/#{code}")
|
9
22
|
|
10
23
|
response.parsed_response if response.success?
|
11
24
|
end
|
12
25
|
|
26
|
+
def options(attribute_code)
|
27
|
+
response = get_request("/attributes/#{attribute_code}/options")
|
28
|
+
|
29
|
+
response.parsed_response if response.success?
|
30
|
+
end
|
31
|
+
|
13
32
|
def option(code, option_code)
|
14
33
|
response = get_request("/attributes/#{code}/options/#{option_code}")
|
15
34
|
|
@@ -4,6 +4,19 @@ require_relative './service_base.rb'
|
|
4
4
|
|
5
5
|
module Akeneo
|
6
6
|
class CategoryService < ServiceBase
|
7
|
+
def all
|
8
|
+
Enumerator.new do |categories|
|
9
|
+
request_url = "/categories?#{limit_param}"
|
10
|
+
|
11
|
+
loop do
|
12
|
+
response = get_request(request_url)
|
13
|
+
extract_collection_items(response).each { |category| categories << category }
|
14
|
+
request_url = extract_next_page_path(response)
|
15
|
+
break unless request_url
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
7
20
|
def find(code)
|
8
21
|
response = get_request("/categories/#{code}")
|
9
22
|
|
@@ -4,6 +4,19 @@ require_relative './service_base.rb'
|
|
4
4
|
|
5
5
|
module Akeneo
|
6
6
|
class FamilyService < ServiceBase
|
7
|
+
def all
|
8
|
+
Enumerator.new do |families|
|
9
|
+
request_url = "/families?#{limit_param}"
|
10
|
+
|
11
|
+
loop do
|
12
|
+
response = get_request(request_url)
|
13
|
+
extract_collection_items(response).each { |family| families << family }
|
14
|
+
request_url = extract_next_page_path(response)
|
15
|
+
break unless request_url
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
7
20
|
def find(code)
|
8
21
|
response = get_request("/families/#{code}")
|
9
22
|
|
@@ -27,10 +27,9 @@ module Akeneo
|
|
27
27
|
load_products(akeneo_product, akeneo_product['family'], parents)
|
28
28
|
end
|
29
29
|
|
30
|
-
def all(with_family: nil)
|
30
|
+
def all(with_family: nil, with_completeness: nil, updated_after: nil)
|
31
31
|
Enumerator.new do |products|
|
32
|
-
path =
|
33
|
-
path += search_with_family_param(with_family) if with_family
|
32
|
+
path = build_path(with_family, with_completeness, updated_after)
|
34
33
|
|
35
34
|
loop do
|
36
35
|
response = get_request(path)
|
@@ -45,10 +44,23 @@ module Akeneo
|
|
45
44
|
patch_request("/products/#{code}", body: options.to_json)
|
46
45
|
end
|
47
46
|
|
47
|
+
def create(options)
|
48
|
+
post_request('/products', body: options.to_json)
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_several(product_objects)
|
52
|
+
patch_for_collection_request('/products', body: product_objects.to_json)
|
53
|
+
end
|
54
|
+
|
48
55
|
private
|
49
56
|
|
50
|
-
def
|
51
|
-
|
57
|
+
def build_path(family, completeness, updated_after)
|
58
|
+
path = "/products?#{pagination_param}&#{limit_param}"
|
59
|
+
path + search_params(
|
60
|
+
family: family,
|
61
|
+
completeness: completeness,
|
62
|
+
updated_after: updated_after
|
63
|
+
)
|
52
64
|
end
|
53
65
|
|
54
66
|
def load_akeneo_parent(code)
|
@@ -58,7 +70,8 @@ module Akeneo
|
|
58
70
|
end
|
59
71
|
|
60
72
|
def load_parents(family, akeneo_parent, akeneo_grand_parent)
|
61
|
-
return [] if akeneo_parent.nil?
|
73
|
+
return [] if akeneo_parent.nil?
|
74
|
+
return [akeneo_parent] if akeneo_grand_parent.nil?
|
62
75
|
|
63
76
|
@product_model_service.all(with_family: family).select do |parent|
|
64
77
|
parent['parent'] == akeneo_grand_parent['code']
|
@@ -12,7 +12,7 @@ module Akeneo
|
|
12
12
|
def published_products(updated_after: nil)
|
13
13
|
Enumerator.new do |products|
|
14
14
|
path = "/published-products?#{pagination_param}"
|
15
|
-
path +=
|
15
|
+
path += search_params(updated_after: updated_after)
|
16
16
|
|
17
17
|
loop do
|
18
18
|
response = get_request(path)
|
data/lib/akeneo/service_base.rb
CHANGED
@@ -9,6 +9,7 @@ module Akeneo
|
|
9
9
|
class ServiceBase
|
10
10
|
prepend Cache
|
11
11
|
|
12
|
+
API_VERSION = 'v1'
|
12
13
|
DEFAULT_PAGINATION_TYPE = :search_after
|
13
14
|
DEFAULT_PAGINATION_LIMIT = 100
|
14
15
|
|
@@ -19,10 +20,28 @@ module Akeneo
|
|
19
20
|
|
20
21
|
private
|
21
22
|
|
23
|
+
def search_params(family: nil, completeness: nil, updated_after: nil)
|
24
|
+
return '' if family.nil? && completeness.nil? && updated_after.nil?
|
25
|
+
|
26
|
+
"&search=#{search_params_hash(family, completeness, updated_after).to_json}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def search_params_hash(family, completeness, updated_after)
|
30
|
+
{}.tap do |hash|
|
31
|
+
hash[:family] = [{ operator: 'IN', value: [family] }] if family
|
32
|
+
hash[:completeness] = [completeness] if completeness
|
33
|
+
hash[:updated] = [{ operator: '>', value: updated_after.strftime('%F %T') }] if updated_after
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
22
37
|
def json_headers
|
23
38
|
{ 'Content-Type' => 'application/json' }
|
24
39
|
end
|
25
40
|
|
41
|
+
def akeneo_collection_headers
|
42
|
+
{ 'Content-Type' => 'application/vnd.akeneo.collection+json' }
|
43
|
+
end
|
44
|
+
|
26
45
|
def authorization_headers
|
27
46
|
{ 'Authorization' => "Bearer #{@access_token}" }
|
28
47
|
end
|
@@ -31,20 +50,38 @@ module Akeneo
|
|
31
50
|
authorization_headers.merge(json_headers)
|
32
51
|
end
|
33
52
|
|
53
|
+
def collection_request_headers
|
54
|
+
authorization_headers.merge(akeneo_collection_headers)
|
55
|
+
end
|
56
|
+
|
34
57
|
def get_request(path, options = {})
|
35
58
|
HTTParty.get(
|
36
|
-
|
59
|
+
build_url(path),
|
37
60
|
options.merge(headers: default_request_headers)
|
38
61
|
)
|
39
62
|
end
|
40
63
|
|
41
64
|
def patch_request(path, options = {})
|
42
65
|
HTTParty.patch(
|
43
|
-
|
66
|
+
build_url(path),
|
67
|
+
options.merge(headers: default_request_headers)
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def post_request(path, options = {})
|
72
|
+
HTTParty.post(
|
73
|
+
build_url(path),
|
44
74
|
options.merge(headers: default_request_headers)
|
45
75
|
)
|
46
76
|
end
|
47
77
|
|
78
|
+
def patch_for_collection_request(path, options = {})
|
79
|
+
HTTParty.patch(
|
80
|
+
build_url(path),
|
81
|
+
options.merge(headers: collection_request_headers)
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
48
85
|
def pagination_param
|
49
86
|
"pagination_type=#{DEFAULT_PAGINATION_TYPE}"
|
50
87
|
end
|
@@ -63,7 +100,17 @@ module Akeneo
|
|
63
100
|
return unless response.success?
|
64
101
|
|
65
102
|
url = response.parsed_response.dig('_links', 'next', 'href')
|
66
|
-
url.to_s.split(
|
103
|
+
url.to_s.split("/api/rest/#{API_VERSION}").last
|
104
|
+
end
|
105
|
+
|
106
|
+
def build_url(path)
|
107
|
+
"#{@url}/api/rest/#{API_VERSION}#{escape_path(path)}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def escape_path(path)
|
111
|
+
return if path.nil?
|
112
|
+
|
113
|
+
path.to_s.gsub(' ', '%20')
|
67
114
|
end
|
68
115
|
end
|
69
116
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: akeneo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AWN Dev Team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: httparty
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.17.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 0.17.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: mime-types
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -179,7 +179,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
181
|
requirements: []
|
182
|
-
|
182
|
+
rubyforge_project:
|
183
|
+
rubygems_version: 2.7.6
|
183
184
|
signing_key:
|
184
185
|
specification_version: 4
|
185
186
|
summary: API client for accessing Akeneo
|