cloudconvert 0.0.5 → 1.0.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.
@@ -0,0 +1,173 @@
1
+ module CloudConvert
2
+ class Base
3
+ extend Forwardable
4
+ include Memoizable
5
+ # @return [Hash]
6
+ attr_reader :attrs
7
+ alias to_h attrs
8
+ alias to_hash to_h
9
+
10
+ class << self
11
+ # Define methods that retrieve the value from attributes
12
+ #
13
+ # @param attrs [Array, Symbol]
14
+ def attr_reader(*attrs)
15
+ attrs.each do |attr|
16
+ define_attribute_method(attr)
17
+ define_predicate_method(attr)
18
+ end
19
+ end
20
+
21
+ # Define collection methods from attributes
22
+ #
23
+ # @param klass [Symbol]
24
+ # @param attrs [Array, Symbol]
25
+ def collection_attr_reader(klass, *attrs)
26
+ attrs.each do |attr|
27
+ define_collection_method(attr, klass)
28
+ define_predicate_method(attr)
29
+ end
30
+ end
31
+
32
+ # Define object methods from attributes
33
+ #
34
+ # @param klass [Symbol]
35
+ # @param attrs [Array, Symbol]
36
+ def object_attr_reader(klass, *attrs)
37
+ attrs.each do |attr|
38
+ define_object_method(attr, klass)
39
+ define_predicate_method(attr)
40
+ end
41
+ end
42
+
43
+ # Define predicate methods from attributes
44
+ #
45
+ # @param attrs [Array, Symbol]
46
+ def predicate_attr_reader(*attrs)
47
+ attrs.each do |attr|
48
+ define_predicate_method(attr)
49
+ end
50
+ end
51
+
52
+ # Define struct methods from attributes
53
+ #
54
+ # @param attrs [Array, Symbol]
55
+ def struct_attr_reader(*attrs)
56
+ attrs.each do |attr|
57
+ define_struct_method(attr)
58
+ define_predicate_method(attr)
59
+ end
60
+ end
61
+
62
+ # Define symbol methods from attributes
63
+ #
64
+ # @param attrs [Array, Symbol]
65
+ def symbol_attr_reader(*attrs)
66
+ attrs.each do |attr|
67
+ define_symbol_method(attr)
68
+ end
69
+ end
70
+
71
+ # Define time methods from attributes
72
+ #
73
+ # @param attrs [Array, Symbol]
74
+ def time_attr_reader(*attrs)
75
+ attrs.each do |attr|
76
+ define_time_method(attr)
77
+ define_predicate_method(attr.to_s.gsub(/_at$/, ""), attr)
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ # Dynamically define a method for an attribute
84
+ #
85
+ # @param key [Symbol]
86
+ # @param klass [Symbol]
87
+ def define_attribute_method(key)
88
+ define_method(key) do
89
+ @attrs[key]
90
+ end
91
+ memoize(key)
92
+ end
93
+
94
+ # Dynamically define a collection method for an attribute
95
+ #
96
+ # @param key [Symbol]
97
+ # @param klass [Symbol]
98
+ def define_collection_method(key, klass)
99
+ define_method(key) do
100
+ collection = @attrs[key] || []
101
+ entity = CloudConvert.const_get(klass)
102
+ Collection.new collection.map { |item| entity.new(item) }
103
+ end
104
+ memoize(key)
105
+ end
106
+
107
+ # Dynamically define a predicate method for an attribute
108
+ #
109
+ # @param key1 [Symbol]
110
+ # @param key2 [Symbol]
111
+ def define_predicate_method(key1, key2 = key1)
112
+ define_method(:"#{key1}?") do
113
+ !attr_falsey_or_empty?(key2)
114
+ end
115
+ memoize(:"#{key1}?")
116
+ end
117
+
118
+ # Dynamically define a object method for an attribute
119
+ #
120
+ # @param key [Symbol]
121
+ def define_object_method(key, klass)
122
+ define_method(key) do
123
+ CloudConvert.const_get(klass).new(@attrs[key]) unless @attrs[key].nil?
124
+ end
125
+ memoize(key)
126
+ end
127
+
128
+ # Dynamically define a struct method for an attribute
129
+ #
130
+ # @param key [Symbol]
131
+ def define_struct_method(key)
132
+ define_method(key) do
133
+ OpenStruct.new(@attrs[key]) unless @attrs[key].nil?
134
+ end
135
+ memoize(key)
136
+ end
137
+
138
+ # Dynamically define a symbol method for an attribute
139
+ #
140
+ # @param key [Symbol]
141
+ def define_symbol_method(key)
142
+ define_method(key) do
143
+ @attrs[key].to_sym unless @attrs[key].nil?
144
+ end
145
+ memoize(key)
146
+ end
147
+
148
+ # Dynamically define a time method for an attribute
149
+ #
150
+ # @param key [Symbol]
151
+ def define_time_method(key)
152
+ define_method(key) do
153
+ Time.parse(@attrs[key]).utc unless @attrs[key].nil?
154
+ end
155
+ memoize(key)
156
+ end
157
+ end
158
+
159
+ # Initializes a new object
160
+ #
161
+ # @param attrs [Hash]
162
+ # @return [CloudConvert::Base]
163
+ def initialize(attrs = {})
164
+ @attrs = attrs || {}
165
+ end
166
+
167
+ private
168
+
169
+ def attr_falsey_or_empty?(key)
170
+ !@attrs[key] || @attrs[key].respond_to?(:empty?) && @attrs[key].empty?
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,107 @@
1
+ module CloudConvert
2
+ class Client
3
+ attr_reader :api_key, :sandbox
4
+
5
+ # Initializes a new Client object
6
+ #
7
+ # @param options [Hash]
8
+ # @return [CloudConvert::Client]
9
+ def initialize(options = {})
10
+ schema = Schemacop::Schema.new do
11
+ req! :api_key, :string
12
+ opt! :sandbox, :boolean, default: false
13
+ end
14
+
15
+ schema.validate! options.reverse_merge!({
16
+ api_key: ENV["CLOUDCONVERT_API_KEY"],
17
+ sandbox: ENV["CLOUDCONVERT_SANDBOX"].to_s.downcase == "true",
18
+ })
19
+
20
+ @api_key = options[:api_key]
21
+ @sandbox = options[:sandbox]
22
+ end
23
+
24
+ # @return [Resources::Jobs]
25
+ def jobs
26
+ @jobs ||= Resources::Jobs.new(self)
27
+ end
28
+
29
+ # @return [Resources::Tasks]
30
+ def tasks
31
+ @tasks ||= Resources::Tasks.new(self)
32
+ end
33
+
34
+ # @return [Resources::Users]
35
+ def users
36
+ @users ||= Resources::Users.new(self)
37
+ end
38
+
39
+ # @param method [Symbol]
40
+ # @param path [String]
41
+ # @param params [Hash]
42
+ # @return [OpenStruct]
43
+ def request(method, path, params = {}, &block)
44
+ response = connection.send(method, path, params, &block)
45
+ raise CloudConvert::Error.from_response(response) unless response.success?
46
+ response.body unless response.body.blank?
47
+ end
48
+
49
+ # @param path [String]
50
+ # @param params [Hash]
51
+ # @return [OpenStruct]
52
+ def get(path, params = {}, &block)
53
+ request(:get, path, params, &block)
54
+ end
55
+
56
+ # @param path [String]
57
+ # @param params [Hash]
58
+ # @return [OpenStruct]
59
+ def post(path, params = {}, &block)
60
+ request(:post, path, params, &block)
61
+ end
62
+
63
+ # @param path [String]
64
+ # @param params [Hash]
65
+ # @return [OpenStruct]
66
+ def delete(path, params = {}, &block)
67
+ request(:delete, path, params, &block)
68
+ end
69
+
70
+ # @param url [String]
71
+ # @return [Tempfile]
72
+ def download(url, *args, **options)
73
+ options[:headers] ||= {}
74
+ options[:headers]["User-Agent"] = USER_AGENT
75
+ Down.download(url, *args, **options)
76
+ end
77
+
78
+ private
79
+
80
+ # @return [String]
81
+ def api_host
82
+ @api_host ||= sandbox ? SANDBOX_URL : API_URL
83
+ end
84
+
85
+ # @return [Faraday::Client]
86
+ def connection
87
+ @connection ||= Faraday.new(url: api_host, headers: headers) do |f|
88
+ f.adapter Faraday.default_adapter
89
+ f.request :json
90
+ f.request :multipart
91
+ f.use CloudConvert::Middleware::ParseJson, content_type: /\bjson$/
92
+ f.use FaradayMiddleware::FollowRedirects, callback: lambda { |response, redirect|
93
+ redirect.request_headers.delete("Content-Length")
94
+ redirect.request_headers.delete("Content-Type")
95
+ }
96
+ end
97
+ end
98
+
99
+ # @return [Hash]
100
+ def headers
101
+ @headers ||= {
102
+ "Authorization": "Bearer #{api_key}",
103
+ "User-Agent": USER_AGENT,
104
+ }
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,15 @@
1
+ module CloudConvert
2
+ class Collection < Array
3
+ attr_reader :links, :meta
4
+
5
+ def initialize(items = [], links = {}, meta = {})
6
+ super(items)
7
+ @links = links
8
+ @meta = meta
9
+ end
10
+
11
+ def where(attrs)
12
+ self.class.new select { |item| attrs.map { |k, v| item.send(k) == v ? true : nil }.compact.length == attrs.length }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module CloudConvert
2
+ class Entity < Base
3
+ attr_reader :id
4
+
5
+ include Equalizer.new(:id)
6
+
7
+ class << self
8
+ def collection(response)
9
+ CloudConvert::Collection.new(
10
+ response.data.collect { |item| new(item) },
11
+ response.links,
12
+ response.meta,
13
+ )
14
+ end
15
+
16
+ def result(response)
17
+ new response.data
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,108 @@
1
+ module CloudConvert
2
+ class Error < StandardError
3
+ # @return [Integer]
4
+ attr_reader :code
5
+
6
+ # @return [OpenStruct]
7
+ attr_reader :errors
8
+
9
+ # Raised when CloudConvert returns a 4xx HTTP status code
10
+ ClientError = Class.new(self)
11
+
12
+ # Raised when CloudConvert returns the HTTP status code 400
13
+ BadRequest = Class.new(ClientError)
14
+
15
+ # Raised when CloudConvert returns the HTTP status code 401
16
+ Unauthorized = Class.new(ClientError)
17
+
18
+ # Raised when CloudConvert returns the HTTP status code 402
19
+ PaymentRequired = Class.new(ClientError)
20
+
21
+ # Raised when CloudConvert returns the HTTP status code 403
22
+ Forbidden = Class.new(ClientError)
23
+
24
+ # Raised when CloudConvert returns the HTTP status code 413
25
+ RequestEntityTooLarge = Class.new(ClientError)
26
+
27
+ # Raised when CloudConvert returns the HTTP status code 404
28
+ NotFound = Class.new(ClientError)
29
+
30
+ # Raised when CloudConvert returns the HTTP status code 406
31
+ NotAcceptable = Class.new(ClientError)
32
+
33
+ # Raised when CloudConvert returns the HTTP status code 422
34
+ UnprocessableEntity = Class.new(ClientError)
35
+
36
+ # Raised when CloudConvert returns the HTTP status code 429
37
+ TooManyRequests = Class.new(ClientError)
38
+
39
+ # Raised when CloudConvert returns a 5xx HTTP status code
40
+ ServerError = Class.new(self)
41
+
42
+ # Raised when CloudConvert returns the HTTP status code 500
43
+ InternalServerError = Class.new(ServerError)
44
+
45
+ # Raised when CloudConvert returns the HTTP status code 502
46
+ BadGateway = Class.new(ServerError)
47
+
48
+ # Raised when CloudConvert returns the HTTP status code 503
49
+ ServiceUnavailable = Class.new(ServerError)
50
+
51
+ # Raised when CloudConvert returns the HTTP status code 504
52
+ GatewayTimeout = Class.new(ServerError)
53
+
54
+ # Raised when CloudConvert returns a media related error
55
+ MediaError = Class.new(self)
56
+
57
+ # Raised when CloudConvert returns an InvalidMedia error
58
+ InvalidMedia = Class.new(MediaError)
59
+
60
+ # Raised when CloudConvert returns a media InternalError error
61
+ MediaInternalError = Class.new(MediaError)
62
+
63
+ # Raised when CloudConvert returns an UnsupportedMedia error
64
+ UnsupportedMedia = Class.new(MediaError)
65
+
66
+ # Raised when an operation subject to timeout takes too long
67
+ TimeoutError = Class.new(self)
68
+
69
+ ERRORS = {
70
+ 400 => CloudConvert::Error::BadRequest,
71
+ 401 => CloudConvert::Error::Unauthorized,
72
+ 402 => CloudConvert::Error::PaymentRequired,
73
+ 403 => CloudConvert::Error::Forbidden,
74
+ 404 => CloudConvert::Error::NotFound,
75
+ 406 => CloudConvert::Error::NotAcceptable,
76
+ 413 => CloudConvert::Error::RequestEntityTooLarge,
77
+ 422 => CloudConvert::Error::UnprocessableEntity,
78
+ 429 => CloudConvert::Error::TooManyRequests,
79
+ 500 => CloudConvert::Error::InternalServerError,
80
+ 502 => CloudConvert::Error::BadGateway,
81
+ 503 => CloudConvert::Error::ServiceUnavailable,
82
+ 504 => CloudConvert::Error::GatewayTimeout,
83
+ }.freeze
84
+
85
+ class << self
86
+ # Create a new error from an HTTP response
87
+ #
88
+ # @param response [Faraday::Response]
89
+ # @return [CloudConvert::Error]
90
+ def from_response(response)
91
+ klass = ERRORS[response.status] || self
92
+ klass.new(response.body.message, response.body.code, response.body.errors)
93
+ end
94
+ end
95
+
96
+ # Initializes a new Error object
97
+ #
98
+ # @param message [Exception, String]
99
+ # @param code [Integer]
100
+ # @return [CloudConvert::Error]
101
+ def initialize(message = "", code = nil, errors = {})
102
+ super(message)
103
+
104
+ @code = code
105
+ @errors = errors
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,14 @@
1
+ module CloudConvert
2
+ class Event < Entity
3
+ include Equalizer.new(:event, :job)
4
+
5
+ # @return [String]
6
+ attr_reader :event
7
+
8
+ # @return [String]
9
+ alias_method :name, :event
10
+
11
+ # @return [Boolean]
12
+ object_attr_reader :Job, :job
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module CloudConvert
2
+ class File < Faraday::FilePart
3
+ def initialize(file, content_type = nil, *parts)
4
+ content_type ||= "text/plain" if file.is_a? StringIO
5
+ content_type ||= MimeMagic.by_magic(file) || MimeMagic.by_path(file)
6
+ super(file, content_type, *parts)
7
+ end
8
+ end
9
+ end