apisync 0.1.0 → 0.1.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 +4 -4
- data/.gitignore +1 -0
- data/README.md +27 -14
- data/apisync.gemspec +5 -1
- data/lib/apisync.rb +26 -2
- data/lib/apisync/exceptions.rb +7 -0
- data/lib/apisync/http/query_string.rb +68 -0
- data/lib/apisync/http/url.rb +73 -0
- data/lib/apisync/http_client.rb +74 -0
- data/lib/apisync/resource.rb +67 -0
- data/lib/apisync/version.rb +2 -2
- metadata +50 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3baebf434178862cf7ad0513124cfa460f1ed8c
|
4
|
+
data.tar.gz: 89cfa8062601ae2a64b15a52072303789e97f027
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e87c8cf404ed809e67588896489dafc1bfcba4a3fdd5e069be68d4f38b38b365f54b9fac016568e15a22c1afbd4b12815a6a03296edcde66e6a62b75f09650e
|
7
|
+
data.tar.gz: c1bd720f4e8700182878c26f649c7b0ddfc10dab926159052194007c22f9646dd22859d7063c7840339058d573dd2278907b4265ef53c75f757240f732c5fb4c
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# Apisync
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
3
|
+
This gem gives you the tools to interact with [apisync.io](apisync.io).
|
6
4
|
|
7
5
|
## Installation
|
8
6
|
|
@@ -12,27 +10,42 @@ Add this line to your application's Gemfile:
|
|
12
10
|
gem 'apisync'
|
13
11
|
```
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
13
|
+
## Usage
|
20
14
|
|
21
|
-
|
15
|
+
### Vanilla Ruby
|
22
16
|
|
23
|
-
|
17
|
+
To create an inventory item:
|
24
18
|
|
25
|
-
|
19
|
+
```ruby
|
20
|
+
client = Apisync.new(api_key: token)
|
21
|
+
client.inventory_items.save({
|
22
|
+
attributes: {
|
23
|
+
ad_template_type: "vehicle",
|
24
|
+
availability: "on-sale",
|
25
|
+
brand: "brand",
|
26
|
+
condition: "new",
|
27
|
+
content_language: "pt-br"
|
28
|
+
# ... more attributes
|
29
|
+
}
|
30
|
+
})
|
31
|
+
```
|
26
32
|
|
27
33
|
## Development
|
28
34
|
|
29
|
-
|
35
|
+
To run tests:
|
36
|
+
|
37
|
+
```
|
38
|
+
bundle exec rspec spec
|
39
|
+
```
|
30
40
|
|
31
|
-
To
|
41
|
+
To release a new version, update the version number in `version.rb`, and then
|
42
|
+
run `bundle exec rake release`, which will create a git tag for the version,
|
43
|
+
push git commits and tags, and push the `.gem` file to
|
44
|
+
[rubygems.org](https://rubygems.org).
|
32
45
|
|
33
46
|
## Contributing
|
34
47
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
48
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/apisync/apisync-ruby.
|
36
49
|
|
37
50
|
## License
|
38
51
|
|
data/apisync.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "apisync"
|
8
8
|
spec.version = Apisync::VERSION
|
9
9
|
spec.authors = ["Alexandre de Oliveira"]
|
10
|
-
spec.email = ["
|
10
|
+
spec.email = ["chavedomundo@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{Official client to apisync.io}
|
13
13
|
spec.homepage = "https://github.com/apisync/apisync-ruby"
|
@@ -20,7 +20,11 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.add_dependency "httparty", "~> 0.13"
|
24
|
+
|
23
25
|
spec.add_development_dependency "bundler", "~> 1.15"
|
24
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
27
|
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
spec.add_development_dependency "awesome_print"
|
29
|
+
spec.add_development_dependency "pry"
|
26
30
|
end
|
data/lib/apisync.rb
CHANGED
@@ -1,5 +1,29 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "httparty"
|
3
|
+
|
1
4
|
require "apisync/version"
|
5
|
+
require "apisync/exceptions"
|
6
|
+
require "apisync/resource"
|
7
|
+
require "apisync/http_client"
|
8
|
+
require "apisync/http/url"
|
9
|
+
require "apisync/http/query_string"
|
10
|
+
|
11
|
+
class Apisync
|
12
|
+
@@api_key = nil
|
13
|
+
|
14
|
+
def initialize(api_key: nil)
|
15
|
+
@api_key = api_key || @@api_key
|
16
|
+
|
17
|
+
raise ArgumentError, "missing keyword: api_key" if @api_key.nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(name, args = {}, &block)
|
21
|
+
# overrides the instance api_key as `authorization`
|
22
|
+
options = args.merge(api_key: @api_key)
|
23
|
+
Apisync::Resource.new(name, options)
|
24
|
+
end
|
2
25
|
|
3
|
-
|
4
|
-
|
26
|
+
def self.api_key=(key)
|
27
|
+
@@api_key = key
|
28
|
+
end
|
5
29
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class Apisync
|
2
|
+
module Http
|
3
|
+
class QueryString
|
4
|
+
def initialize(filters:)
|
5
|
+
@filters = filters
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_s
|
9
|
+
result = ""
|
10
|
+
result << format_filters if @filters
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# Takes a list of `[key]=value` strings and maps them adding `"filter"`
|
17
|
+
# as prefix.
|
18
|
+
#
|
19
|
+
# Results in `filter[key]=value&filter[key2]=value2`.
|
20
|
+
def format_filters
|
21
|
+
recursive_brackets(@filters)
|
22
|
+
.flatten
|
23
|
+
.map { |filter| "filter#{filter}" }
|
24
|
+
.join("&")
|
25
|
+
end
|
26
|
+
|
27
|
+
# Takes a hash such as
|
28
|
+
#
|
29
|
+
# {
|
30
|
+
# field_one: 'value1',
|
31
|
+
# metadata: {
|
32
|
+
# field_two: "value2",
|
33
|
+
# field_three: "value3"
|
34
|
+
# }
|
35
|
+
# }
|
36
|
+
#
|
37
|
+
# and returns
|
38
|
+
#
|
39
|
+
# [
|
40
|
+
# "[field-one]=value1",
|
41
|
+
# "[metadata][field-two]=value2",
|
42
|
+
# "[metadata][field-three]=value3"
|
43
|
+
# ]
|
44
|
+
#
|
45
|
+
# This can be used for creating filter querystrings.
|
46
|
+
def recursive_brackets(hash, prefix = "")
|
47
|
+
result = []
|
48
|
+
hash.each do |key, value|
|
49
|
+
key = hyphenize(key.to_s)
|
50
|
+
if value.is_a?(Hash)
|
51
|
+
prefix = "#{prefix}[#{key}]"
|
52
|
+
top_nodes = recursive_brackets(value, prefix)
|
53
|
+
result << top_nodes
|
54
|
+
else
|
55
|
+
result << "#{prefix}[#{key}]=#{value}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
result
|
60
|
+
end
|
61
|
+
|
62
|
+
# Converts application_id in application-id.
|
63
|
+
def hyphenize(string)
|
64
|
+
string.gsub(/_/, "-")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
class Apisync
|
2
|
+
module Http
|
3
|
+
|
4
|
+
# Responsible for generating URLs
|
5
|
+
class Url
|
6
|
+
DEFAULT_HOST = "https://api.apisync.io"
|
7
|
+
|
8
|
+
# - resource_name: a name in plural such as 'users', 'profiles' etc.
|
9
|
+
# - id: id of the resource that you're looking for
|
10
|
+
# - filters: these will define what's in the query string, such as
|
11
|
+
# 'filter[application-id]=value'
|
12
|
+
# - options: allows you to pass options such 'host'. Accepted options are
|
13
|
+
#
|
14
|
+
# - host: a custom host for the URL, defaults to DEFAULT_HOST
|
15
|
+
def initialize(resource_name:, id: nil, filters: nil, options:)
|
16
|
+
@resource_name = resource_name
|
17
|
+
@id = id
|
18
|
+
@filters = filters
|
19
|
+
@options = {
|
20
|
+
host: nil
|
21
|
+
}.merge(options)
|
22
|
+
end
|
23
|
+
|
24
|
+
# to_s
|
25
|
+
#
|
26
|
+
# Takes a host, api_version, resource name and id and form the URL. Then
|
27
|
+
# pass filters and other options into QueryString class which will return
|
28
|
+
# whatever is after the `?` symbol.
|
29
|
+
#
|
30
|
+
# Returns a string such as
|
31
|
+
#
|
32
|
+
# 'https://api.apisync.io/inventory-items?filter[application-id]=abc'
|
33
|
+
#
|
34
|
+
# If there are no query strings, omits the `?`
|
35
|
+
#
|
36
|
+
# 'https://api.apisync.io/inventory-items'
|
37
|
+
#
|
38
|
+
def to_s
|
39
|
+
url = [
|
40
|
+
host,
|
41
|
+
api_version,
|
42
|
+
normalized_resource_name,
|
43
|
+
@id
|
44
|
+
].compact.join("/")
|
45
|
+
url = remove_duplicated_slashes(url)
|
46
|
+
[url, query_string].compact.join("?")
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def api_version
|
52
|
+
Apisync::HttpClient::VERSION_PREFIX
|
53
|
+
end
|
54
|
+
|
55
|
+
def host
|
56
|
+
@options[:host] || DEFAULT_HOST
|
57
|
+
end
|
58
|
+
|
59
|
+
def query_string
|
60
|
+
str = Apisync::Http::QueryString.new(filters: @filters).to_s
|
61
|
+
str if str != ""
|
62
|
+
end
|
63
|
+
|
64
|
+
def normalized_resource_name
|
65
|
+
@resource_name.to_s.downcase.gsub("_", "-")
|
66
|
+
end
|
67
|
+
|
68
|
+
def remove_duplicated_slashes(string)
|
69
|
+
string.gsub(/([^:])\/\//, '\1/')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class Apisync
|
2
|
+
class HttpClient
|
3
|
+
VERSION_PREFIX = "".freeze
|
4
|
+
|
5
|
+
HEADER = {
|
6
|
+
"Content-Type" => "application/vnd.api+json",
|
7
|
+
"Accept" => "application/vnd.api+json"
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
def self.post(resource_name:, data:, options: {})
|
11
|
+
url = Apisync::Http::Url.new(
|
12
|
+
resource_name: resource_name,
|
13
|
+
options: options
|
14
|
+
)
|
15
|
+
payload = payload_from_data(data)
|
16
|
+
HTTParty.post(
|
17
|
+
url.to_s,
|
18
|
+
body: {data: payload}.to_json,
|
19
|
+
headers: header(api_key: options[:api_key])
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.put(resource_name:, id:, data:, options: {})
|
24
|
+
raise Apisync::UrlAndPayloadIdMismatch unless id == data[:id]
|
25
|
+
|
26
|
+
url = Apisync::Http::Url.new(
|
27
|
+
resource_name: resource_name,
|
28
|
+
id: id,
|
29
|
+
options: options
|
30
|
+
)
|
31
|
+
payload = payload_from_data(data)
|
32
|
+
HTTParty.put(
|
33
|
+
url.to_s,
|
34
|
+
body: {data: payload}.to_json,
|
35
|
+
headers: header(api_key: options[:api_key])
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.get(resource_name:, id: nil, filters: nil, options: {})
|
40
|
+
raise Apisync::InvalidFilter if !filters.nil? && !filters.is_a?(Hash)
|
41
|
+
|
42
|
+
url = Apisync::Http::Url.new(
|
43
|
+
resource_name: resource_name,
|
44
|
+
id: id,
|
45
|
+
filters: filters,
|
46
|
+
options: options
|
47
|
+
)
|
48
|
+
HTTParty.get(url.to_s, headers: header(api_key: options[:api_key]))
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def self.header(api_key: nil)
|
54
|
+
final = HEADER
|
55
|
+
if api_key
|
56
|
+
final = final.merge("Authorization" => "ApiToken #{api_key}")
|
57
|
+
end
|
58
|
+
final
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.payload_from_data(data)
|
62
|
+
transformed_payload = {}
|
63
|
+
data.each do |key, value|
|
64
|
+
if value.is_a?(Hash)
|
65
|
+
transformed_payload[key.to_s] = payload_from_data(value)
|
66
|
+
else
|
67
|
+
new_key = key.to_s.gsub("_", "-").to_sym
|
68
|
+
transformed_payload[new_key] = value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
transformed_payload
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class Apisync
|
2
|
+
class Resource
|
3
|
+
def initialize(name, options = {})
|
4
|
+
@name = name
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
# Saves a resource.
|
9
|
+
#
|
10
|
+
# When the resource has an id in `data`, a `PUT` request is done. Otherwise
|
11
|
+
# a `POST` takes place.
|
12
|
+
#
|
13
|
+
def save(data)
|
14
|
+
data[:type] = @name.to_s.gsub("_", "-")
|
15
|
+
if data[:id].nil?
|
16
|
+
post(data)
|
17
|
+
else
|
18
|
+
put(data)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns all resources that match the conditions passed in.
|
23
|
+
#
|
24
|
+
# 1. To find a resource by its id:
|
25
|
+
#
|
26
|
+
# get(id: 'customer-id')
|
27
|
+
#
|
28
|
+
# 2. To find a resource by a column value
|
29
|
+
#
|
30
|
+
# get(filters: {column_name: 'customer-id' }})
|
31
|
+
#
|
32
|
+
def get(conditions)
|
33
|
+
http_client.get(
|
34
|
+
resource_name: @name,
|
35
|
+
id: conditions[:id],
|
36
|
+
filters: conditions[:filters],
|
37
|
+
options: @options
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
|
44
|
+
def post(data)
|
45
|
+
http_client.post(
|
46
|
+
resource_name: @name,
|
47
|
+
data: data,
|
48
|
+
options: @options
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def put(data)
|
53
|
+
http_client.put(
|
54
|
+
resource_name: @name,
|
55
|
+
id: data[:id],
|
56
|
+
data: data,
|
57
|
+
options: @options
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def http_client
|
64
|
+
Apisync::HttpClient
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/apisync/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.1.
|
1
|
+
class Apisync
|
2
|
+
VERSION = "0.1.3"
|
3
3
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apisync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandre de Oliveira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.13'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.13'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,9 +66,37 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: awesome_print
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
55
97
|
description:
|
56
98
|
email:
|
57
|
-
-
|
99
|
+
- chavedomundo@gmail.com
|
58
100
|
executables:
|
59
101
|
- console
|
60
102
|
- setup
|
@@ -72,6 +114,11 @@ files:
|
|
72
114
|
- bin/console
|
73
115
|
- bin/setup
|
74
116
|
- lib/apisync.rb
|
117
|
+
- lib/apisync/exceptions.rb
|
118
|
+
- lib/apisync/http/query_string.rb
|
119
|
+
- lib/apisync/http/url.rb
|
120
|
+
- lib/apisync/http_client.rb
|
121
|
+
- lib/apisync/resource.rb
|
75
122
|
- lib/apisync/version.rb
|
76
123
|
homepage: https://github.com/apisync/apisync-ruby
|
77
124
|
licenses:
|