cropio-ruby 0.1.2 → 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/README.md +4 -2
- data/Rakefile +1 -1
- data/cropio-ruby.gemspec +22 -15
- data/lib/cropio.rb +8 -0
- data/lib/cropio/connection/authenticable.rb +19 -8
- data/lib/cropio/connection/configurable.rb +8 -4
- data/lib/cropio/connection/proxiable.rb +10 -5
- data/lib/cropio/connection/proxy.rb +2 -0
- data/lib/cropio/misc/string_inflector.rb +9 -6
- data/lib/cropio/resource/attributes.rb +6 -5
- data/lib/cropio/resource/base.rb +46 -29
- data/lib/cropio/resources.rb +1 -1
- data/lib/cropio/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: afd6f4a57445477df70033561a85459d8f7b69e2
|
4
|
+
data.tar.gz: 799fcb92903ae02aaa589e2209f602434032b9e9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73783fbd5238a14da0bc6b7f00b38ac169f921abe1bf7502337b33d49cbb35f201c330a2cf4eba3eb46d5c2685d6bc0bc6ef4289e1f9981ec08f578b0535baba
|
7
|
+
data.tar.gz: ead1b0a204f01ec45fe396a66402040f34a32f24fa46433f19381bca4b79d4ac7dcae8c8a37bf55ec24c536c4d3fcbf5ba458292216c2d7656d54d7c9865296d
|
data/README.md
CHANGED
@@ -23,7 +23,9 @@ Or install it yourself as:
|
|
23
23
|
|
24
24
|
Require it:
|
25
25
|
|
26
|
-
|
26
|
+
```ruby
|
27
|
+
require 'cropio'
|
28
|
+
```
|
27
29
|
|
28
30
|
To load Cropio resources to current namespace:
|
29
31
|
|
@@ -36,7 +38,7 @@ try to request some data from Cropio gem will get authentication token.
|
|
36
38
|
|
37
39
|
```ruby
|
38
40
|
Cropio.credentials = {
|
39
|
-
email: 'your account email,
|
41
|
+
email: 'your account email',
|
40
42
|
password: 'your password'
|
41
43
|
}
|
42
44
|
|
data/Rakefile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
data/cropio-ruby.gemspec
CHANGED
@@ -4,25 +4,32 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'cropio/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
7
|
+
spec.name = 'cropio-ruby'
|
8
|
+
spec.version = Cropio::VERSION
|
9
|
+
spec.authors = ['Sergey Vernidub']
|
10
|
+
spec.email = ['info@cropio.com']
|
11
11
|
|
12
|
-
spec.summary
|
13
|
-
spec.description = %q{Cropio-Ruby provides simple ActiveRecord-like wrappings for Cropio API}
|
14
|
-
spec.homepage = "https://cropio.com"
|
12
|
+
spec.summary = 'Cropio API bindings for Ruby'
|
15
13
|
|
16
|
-
spec.
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
spec.description = <<STR
|
15
|
+
Cropio-Ruby provides simple ActiveRecord-like wrappings for Cropio API
|
16
|
+
STR
|
17
|
+
|
18
|
+
spec.homepage = 'https://cropio.com'
|
19
|
+
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
21
|
+
f.match(%r{^(test|spec|features)/})
|
22
|
+
end
|
23
|
+
|
24
|
+
spec.bindir = 'exe'
|
25
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
+
spec.require_paths = ['lib']
|
20
27
|
|
21
28
|
spec.add_dependency 'json'
|
22
29
|
spec.add_dependency 'rest-client'
|
23
30
|
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
31
|
+
spec.add_development_dependency 'bundler', '~> 1.9'
|
32
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
33
|
+
spec.add_development_dependency 'pry'
|
34
|
+
spec.add_development_dependency 'byebug'
|
28
35
|
end
|
data/lib/cropio.rb
CHANGED
@@ -5,11 +5,19 @@ require 'cropio/connection'
|
|
5
5
|
require 'cropio/resource'
|
6
6
|
require 'cropio/resources'
|
7
7
|
|
8
|
+
# Cropio-Ruby provides simple ActiveRecord-like wrappings
|
9
|
+
# for Cropio API. Currently it supports Cropio APIv3.
|
10
|
+
#
|
11
|
+
# Main gem's module Cropio contains accessors for credentials and other stuff
|
8
12
|
module Cropio
|
13
|
+
# Getter for credentials
|
9
14
|
def self.credentials
|
10
15
|
@credentials
|
11
16
|
end
|
12
17
|
|
18
|
+
# Setter for credentials,
|
19
|
+
# accepts Hash or OpenStruct with email and password or api_token
|
20
|
+
# as param
|
13
21
|
def self.credentials=(credentials)
|
14
22
|
case credentials
|
15
23
|
when Hash
|
@@ -1,30 +1,36 @@
|
|
1
1
|
module Cropio
|
2
2
|
module Connection
|
3
|
+
# Contains authentication options for connection.
|
3
4
|
module Authenticable
|
5
|
+
# Public interface for authentication request
|
4
6
|
def authenticate!
|
5
7
|
auth_request
|
6
8
|
end
|
7
9
|
|
8
10
|
protected
|
9
11
|
|
12
|
+
# Define wrappers around specified methods to be sure
|
13
|
+
# they are authenticated.
|
10
14
|
def authenticate_before(*methods)
|
11
15
|
methods.each do |method_name|
|
12
16
|
unauthentificated_method = method(method_name)
|
13
17
|
singleton_class.send(:define_method, method_name) do |*args|
|
14
|
-
authenticate!
|
18
|
+
authenticate! unless authenticated?
|
15
19
|
unauthentificated_method.call(*args)
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
24
|
+
# Send authentication request.
|
20
25
|
def auth_request
|
21
26
|
process_result RestClient.post(url_for('sign_in'),
|
22
|
-
|
23
|
-
|
27
|
+
auth_request_params.to_json,
|
28
|
+
authentication_headers)
|
24
29
|
rescue RestClient::Unauthorized => e
|
25
30
|
process_result(e.http_body)
|
26
31
|
end
|
27
32
|
|
33
|
+
# Process result returned by authentication request.
|
28
34
|
def process_result(result)
|
29
35
|
result = JSON.parse(result)
|
30
36
|
|
@@ -36,6 +42,7 @@ module Cropio
|
|
36
42
|
end
|
37
43
|
end
|
38
44
|
|
45
|
+
# Return params based on user credentials.
|
39
46
|
def auth_request_params
|
40
47
|
{
|
41
48
|
user_login: {
|
@@ -44,18 +51,22 @@ module Cropio
|
|
44
51
|
}
|
45
52
|
}
|
46
53
|
rescue NoMethodError => e
|
47
|
-
|
48
|
-
fail "Cropio credentials is not specified: #{e.name}"
|
49
|
-
else
|
50
|
-
raise e
|
51
|
-
end
|
54
|
+
process_auth_params_error(e) || raise(e)
|
52
55
|
end
|
53
56
|
|
57
|
+
# Returns true if user has api token.
|
54
58
|
def authenticated?
|
55
59
|
!Cropio.credentials.api_token.nil?
|
56
60
|
rescue NoMethodError => e
|
57
61
|
e.name == :api_token ? false : raise(e)
|
58
62
|
end
|
63
|
+
|
64
|
+
# Process NoMethodError and prints norification if
|
65
|
+
# exeption was produced by empty credentials.
|
66
|
+
def process_auth_params_error(e)
|
67
|
+
return unless %i(email password).include?(e.name)
|
68
|
+
fail "Cropio credentials is not specified: #{e.name}"
|
69
|
+
end
|
59
70
|
end
|
60
71
|
end
|
61
72
|
end
|
@@ -1,23 +1,27 @@
|
|
1
1
|
module Cropio
|
2
2
|
module Connection
|
3
|
+
# Contains logic for requests configuration
|
4
|
+
# like appending headers to requests.
|
3
5
|
module Configurable
|
4
|
-
|
6
|
+
# Cropio's server and API's entry point url
|
5
7
|
BASE_URL = 'https://cropio.com/api/v3'
|
6
8
|
|
7
9
|
protected
|
8
10
|
|
11
|
+
# Returns headers set for request.
|
9
12
|
def headers
|
10
13
|
authenticated? ? authenticated_headers : authentication_headers
|
11
14
|
end
|
12
15
|
|
16
|
+
# Returns headers for authentication query.
|
13
17
|
def authentication_headers
|
14
18
|
{ content_type: :json, accept: :json }
|
15
19
|
end
|
16
20
|
|
21
|
+
# Returns headers for authenticated queries.
|
17
22
|
def authenticated_headers
|
18
|
-
authentication_headers.merge(
|
19
|
-
'X-User-Api-Token' => Cropio.credentials.api_token
|
20
|
-
})
|
23
|
+
authentication_headers.merge(
|
24
|
+
'X-User-Api-Token' => Cropio.credentials.api_token)
|
21
25
|
end
|
22
26
|
end
|
23
27
|
end
|
@@ -1,20 +1,25 @@
|
|
1
|
-
require'rest-client'
|
1
|
+
require 'rest-client'
|
2
2
|
|
3
3
|
module Cropio
|
4
4
|
module Connection
|
5
|
+
# Contains logic of proxing calls to HTTPS requests.
|
5
6
|
module Proxiable
|
6
|
-
|
7
|
-
|
7
|
+
# Accepts reources name and params to perform HTTPS GET request.
|
8
|
+
def get(resource, query = {})
|
9
|
+
proxy(method: :get, url: url_for(resource), headers: { params: query })
|
8
10
|
end
|
9
11
|
|
12
|
+
# Accepts reources name and params to perform HTTPS POST request.
|
10
13
|
def post(resource, data)
|
11
14
|
proxy(method: :post, url: url_for(resource), data: data)
|
12
15
|
end
|
13
16
|
|
17
|
+
# Accepts reources name and params to perform HTTPS PATCH request.
|
14
18
|
def patch(resource, data)
|
15
19
|
proxy(method: :patch, url: url_for(resource), data: data)
|
16
20
|
end
|
17
21
|
|
22
|
+
# Accepts reources name and params to perform HTTPS DELETE request.
|
18
23
|
def delete(resource)
|
19
24
|
proxy(method: :delete, url: url_for(resource))
|
20
25
|
end
|
@@ -41,12 +46,12 @@ module Cropio
|
|
41
46
|
|
42
47
|
def proxy_post(options)
|
43
48
|
RestClient.post(options[:url],
|
44
|
-
{data: options[:data]}, options[:headers])
|
49
|
+
{ data: options[:data] }, options[:headers])
|
45
50
|
end
|
46
51
|
|
47
52
|
def proxy_patch(options)
|
48
53
|
RestClient.patch(options[:url],
|
49
|
-
|
54
|
+
{ data: options[:data] }, options[:headers])
|
50
55
|
end
|
51
56
|
|
52
57
|
def proxy_delete(options)
|
@@ -1,21 +1,24 @@
|
|
1
1
|
module Cropio
|
2
|
+
# StringInflector contains operations for strings.
|
3
|
+
# We think it is bad idea to require active_support for this.
|
2
4
|
class StringInflector
|
3
5
|
class << self
|
4
6
|
def underscore(string)
|
5
7
|
string
|
6
8
|
.gsub(/::/, '/')
|
7
|
-
.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
8
|
-
.gsub(/([a-z\d])([A-Z])/,'\1_\2')
|
9
|
-
.tr(
|
9
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
10
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
11
|
+
.tr('-', '_')
|
10
12
|
.downcase
|
11
13
|
end
|
12
14
|
|
13
|
-
#
|
15
|
+
# Returns pluralized form for word passed as param.
|
16
|
+
# It is simple implementation - for resources plural forms only.
|
14
17
|
def pluralize(string)
|
15
18
|
if string[-1] == 'y'
|
16
|
-
"#{
|
19
|
+
"#{string[0..(string.length - 2)]}ies"
|
17
20
|
else
|
18
|
-
"#{
|
21
|
+
"#{string}s"
|
19
22
|
end
|
20
23
|
end
|
21
24
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Cropio
|
2
2
|
module Resource
|
3
|
+
# Defines accessors for resource attrubutes.
|
3
4
|
module Attributes
|
4
5
|
def self.included(base)
|
5
6
|
base.send(:attr_accessor, :attributes)
|
@@ -36,7 +37,7 @@ module Cropio
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def define_attribute_getter(attribute_name)
|
39
|
-
|
40
|
+
instance_eval "
|
40
41
|
def #{attribute_name}
|
41
42
|
attributes['#{attribute_name}']
|
42
43
|
end
|
@@ -44,7 +45,7 @@ module Cropio
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def define_attribute_setter(attribute_name)
|
47
|
-
|
48
|
+
instance_eval "
|
48
49
|
def #{attribute_name}=(val)
|
49
50
|
attributes['#{attribute_name}'] = val
|
50
51
|
end
|
@@ -52,7 +53,7 @@ module Cropio
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def define_attribute_question(attribute_name)
|
55
|
-
|
56
|
+
instance_eval "
|
56
57
|
def #{attribute_name}?
|
57
58
|
!attributes['#{attribute_name}'].nil?
|
58
59
|
end
|
@@ -61,8 +62,8 @@ module Cropio
|
|
61
62
|
|
62
63
|
def method_missing(name, *attrs, &block)
|
63
64
|
name = name.to_s
|
64
|
-
attr_name = name.
|
65
|
-
if attributes.
|
65
|
+
attr_name = name.delete('=')
|
66
|
+
if attributes.key?(attr_name)
|
66
67
|
define_attributes_accessors
|
67
68
|
name == attr_name ? send(name) : send(name, attrs.first)
|
68
69
|
else
|
data/lib/cropio/resource/base.rb
CHANGED
@@ -1,81 +1,94 @@
|
|
1
1
|
module Cropio
|
2
2
|
module Resource
|
3
|
+
# Represents ActiveRecord::Base-like model's class
|
4
|
+
# with Cropio data selection and mutation.
|
3
5
|
class Base
|
4
6
|
include Attributes
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
PROXY = Cropio::Connection::Proxy
|
9
|
+
LIMIT = 1000
|
8
10
|
|
9
|
-
def initialize(attributes={})
|
11
|
+
def initialize(attributes = {})
|
10
12
|
self.attributes = attributes
|
11
13
|
end
|
12
14
|
|
15
|
+
# Returns name of Resource
|
13
16
|
def self.resource_name
|
14
17
|
@resource_name ||= StringInflector.underscore(name.split('::').last)
|
15
18
|
end
|
16
19
|
|
20
|
+
# Return pluralized version of Resource's name
|
17
21
|
def self.resources_name
|
18
22
|
@resources_name ||= StringInflector.pluralize(resource_name)
|
19
23
|
end
|
20
24
|
|
25
|
+
# Get all resources.
|
21
26
|
def self.all
|
22
27
|
to_instances(get_all_chunks)
|
23
28
|
end
|
24
29
|
|
30
|
+
# Count all resources.
|
25
31
|
def self.count
|
26
32
|
all.count
|
27
33
|
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
# Returns persistance of the resource.
|
36
|
+
# Resource is persisted if it is saved
|
37
|
+
# and not deleted, if this resource exists
|
38
|
+
# on Cropio servers.
|
32
39
|
def persisted?
|
33
|
-
|
34
|
-
@persisted = false
|
35
|
-
end
|
36
|
-
|
37
|
-
@persisted
|
40
|
+
@persisted.nil? && (@persisted ||= false)
|
38
41
|
end
|
39
42
|
|
43
|
+
# Saves current resource to Cropio.
|
40
44
|
def save
|
41
|
-
self.attributes =
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
self.attributes =
|
46
|
+
if persisted?
|
47
|
+
PROXY.patch("#{resources_name}/#{id}", attributes)
|
48
|
+
else
|
49
|
+
@persisted = true
|
50
|
+
PROXY.post(resources_name, attributes)
|
51
|
+
end
|
47
52
|
end
|
48
53
|
|
54
|
+
# Remove this resource from Cropio.
|
49
55
|
def destroy
|
50
56
|
if persisted?
|
51
|
-
|
57
|
+
PROXY.delete("#{resources_name}/#{id}")
|
52
58
|
@persisted = false
|
53
59
|
true
|
54
60
|
else
|
55
|
-
|
61
|
+
fail 'Cropio record is not persisted!'
|
56
62
|
end
|
57
63
|
end
|
58
64
|
|
59
65
|
private
|
66
|
+
|
67
|
+
# Returns pluralized name of own type.
|
60
68
|
def resources_name
|
61
69
|
self.class.resources_name
|
62
70
|
end
|
63
71
|
|
64
|
-
|
72
|
+
# Download resources from Cropio by Chunks.
|
73
|
+
def self.get_all_chunks(options = {})
|
65
74
|
response = nil
|
66
75
|
buffer = []
|
67
|
-
limit = options[:limit] || (2
|
68
|
-
while
|
69
|
-
|
70
|
-
limit
|
71
|
-
offset = buffer.any? ? buffer.last['id'] + 1 : 0
|
72
|
-
response = get_chunk(limit: chunk_size, from_id: offset)
|
76
|
+
limit = options[:limit] || (2**32 - 1)
|
77
|
+
while data?(response) && limit > 0
|
78
|
+
limit -= limit < LIMIT ? limit : LIMIT
|
79
|
+
response = get_chunk(limit: limit, from_id: offset(buffer))
|
73
80
|
buffer += response['data']
|
74
81
|
end
|
75
82
|
buffer
|
76
83
|
end
|
77
84
|
|
78
|
-
|
85
|
+
# Gets offset for next chunk during download.
|
86
|
+
def self.offset(buffer)
|
87
|
+
buffer.any? ? buffer.last['id'] + 1 : 0
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns false if chunk is not empty.
|
91
|
+
def self.data?(response = nil)
|
79
92
|
if response.nil?
|
80
93
|
true
|
81
94
|
else
|
@@ -83,17 +96,21 @@ module Cropio
|
|
83
96
|
end
|
84
97
|
end
|
85
98
|
|
99
|
+
# Download chunk from Cropio.
|
86
100
|
def self.get_chunk(options)
|
87
|
-
|
88
|
-
|
101
|
+
PROXY.get(resources_name,
|
102
|
+
limit: options[:limit],
|
103
|
+
from_id: options[:from_id])
|
89
104
|
end
|
90
105
|
|
106
|
+
# Converts each received attribute's hash to resources.
|
91
107
|
def self.to_instances(attr_sets)
|
92
108
|
attr_sets.map do |attr_set|
|
93
109
|
to_instance(attr_set)
|
94
110
|
end
|
95
111
|
end
|
96
112
|
|
113
|
+
# Converts specified attribute's hash to resource.
|
97
114
|
def self.to_instance(attr_set)
|
98
115
|
new(attr_set).tap do |resource|
|
99
116
|
resource.instance_eval do
|
data/lib/cropio/resources.rb
CHANGED
data/lib/cropio/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cropio-ruby
|
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
|
- Sergey Vernidub
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -94,7 +94,8 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
-
description:
|
97
|
+
description: |
|
98
|
+
Cropio-Ruby provides simple ActiveRecord-like wrappings for Cropio API
|
98
99
|
email:
|
99
100
|
- info@cropio.com
|
100
101
|
executables: []
|