printnode 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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c4ba5de2c1f7ad599ae097006cb43a39f93bd5c5
4
+ data.tar.gz: 7f8decb443228851248cdd22e304144341c00ef9
5
+ SHA512:
6
+ metadata.gz: 028e786c6a0bd47c1fa892ce288283b22d2832ec8d907ff4a58e427a0cf03fd82061d5f01b24a3cac3aac82e42e1168346f2f7535c2244ec9617bdaf63a9f74d
7
+ data.tar.gz: b02819ee3ee78c53912ad1bc80482cfa051b5574286e862021760bb5a8fe4735c5264e67bb945f539876c924da905636aeedb76bd45e56e2edbc67bd1496579f
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+
3
+ require 'printnode/client'
4
+ require 'printnode/api_exception'
5
+ require 'printnode/auth'
6
+ require 'printnode/account'
7
+ require 'printnode/printjob'
@@ -0,0 +1,26 @@
1
+ module PrintNode
2
+ class Account
3
+ attr_accessor :firstname
4
+ attr_accessor :lastname
5
+ attr_accessor :email
6
+ attr_accessor :password
7
+ attr_accessor :creator_ref
8
+
9
+ def to_hash
10
+ hash = {}
11
+ hash['firstname'] = @firstname
12
+ hash['lastname'] = @lastname
13
+ hash['email'] = @email
14
+ hash['password'] = @password
15
+ hash['creatorRef'] = @creator_ref if @creator_ref
16
+ hash
17
+ end
18
+
19
+ def initialize(firstname, lastname, email, password)
20
+ @firstname = firstname
21
+ @lastname = lastname
22
+ @email = email
23
+ @password = password
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,16 @@
1
+ module PrintNode
2
+ # An error class for HTTP errors
3
+ # @author Jake Torrance
4
+ # @author PrintNode
5
+ class APIError < StandardError
6
+ attr_reader :object
7
+
8
+ # Initializes an object or message to use in the error.
9
+ # == Paramters:
10
+ # object::
11
+ # object to show error messages about.
12
+ def initialize(object)
13
+ @object = object
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ module PrintNode
2
+ # Handles which credentials we are using
3
+ # @author Jake Torrance
4
+ # @author PrintNode
5
+ class Auth
6
+ # Initalizes our credentials
7
+ #
8
+ # @param value_a [String] two arguments : this will be an email address.
9
+ # With one, it is an API-Key.
10
+ # @param value_b [String] The password relative to the email set in value_a.
11
+ def initialize(value_a, value_b = nil)
12
+ if value_b
13
+ @email = value_a
14
+ @password = value_b
15
+ else
16
+ @apikey = value_a
17
+ end
18
+ end
19
+ # Returns correctly formatted credentials for HTTP::Request.basic_auth
20
+ #
21
+ # == Returns:
22
+ # An array of with our credentials.
23
+ def credentials
24
+ @apikey ? [@apikey, ''] : [@email, @password]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,469 @@
1
+ require 'net/https'
2
+ require 'uri'
3
+ require 'json'
4
+ require 'ostruct'
5
+ require 'base64'
6
+ require 'cgi'
7
+
8
+ module PrintNode
9
+ # Handles all requests and API access.
10
+ # @author Jake Torrance
11
+ # @author PrintNode
12
+ class Client
13
+ def escape_with_types(obj)
14
+ obj = obj.to_s unless obj.is_a?(String)
15
+ CGI.escape(obj)
16
+ end
17
+
18
+ attr_reader :headers
19
+ # Initializes auth object, api url and headers.
20
+ #
21
+ # @param auth [PrintNode::Auth] auth object with credentials.
22
+ # @param api_url [String] api_url to be used in requests.
23
+ #
24
+ # @see PrintNode::Auth
25
+ def initialize(auth, api_url = 'https://api.printnode.com')
26
+ @auth = auth
27
+ @api_url = api_url
28
+ @headers = {}
29
+ end
30
+
31
+ # parses any hashes in an array to OpenStructs.
32
+ #
33
+ # @param array [Array] the array we want to parse.
34
+ #
35
+ # == Returns:
36
+ # An array with all hashes inside it made into OpenStructs.
37
+ def parse_array_to_struct(array)
38
+ output = []
39
+ array.each do |h|
40
+ if h.is_a?(Hash)
41
+ output.push(parse_hash_to_struct(h))
42
+ elsif h.is_a?(Array)
43
+ output.push(parse_array_to_struct(h))
44
+ else
45
+ output.push(h)
46
+ end
47
+ end
48
+ output
49
+ end
50
+
51
+ # parses any hashes in a hash to OpenStructs. Parses any arrays to check if they have hashes to parse. Creates an OpenStruct for the hash.
52
+ #
53
+ # @param hash [Hash] the hash we want to parse.
54
+ #
55
+ # == Returns:
56
+ # A hash that is an OpenStruct, with all hashes inside it made into OpenStructs.
57
+ def parse_hash_to_struct(hash)
58
+ hash.each do |(k, v)|
59
+ hash[k] = parse_hash_to_struct(v) if v.is_a?(Hash)
60
+ hash[k] = parse_array_to_struct(v) if v.is_a?(Array)
61
+ end
62
+ OpenStruct.new hash
63
+ end
64
+
65
+ # Sets authentication via an id of a Child Account.
66
+ #
67
+ # @param id [int] The id of the Child Account.
68
+ def child_account_by_id(id)
69
+ @headers = { 'X-Child-Account-By-Id' => id }
70
+ end
71
+
72
+ # Sets authentication via an email of a Child Account.
73
+ #
74
+ # @param email [String] the email of the Child Account.
75
+ def child_account_by_email(email)
76
+ @headers = { 'X-Child-Account-By-Email' => email }
77
+ end
78
+
79
+ # Sets authentication via the creator reference of a Child Account.
80
+ #
81
+ # @param creator_ref [String] the creator reference of the Child Account.
82
+ def child_account_by_creator_ref(creator_ref)
83
+ @headers = { 'X-Child-Account-By-CreatorRef' => creator_ref }
84
+ end
85
+
86
+ # Creates a response object out of a Net::HTTP::(request method).
87
+ #
88
+ # @param request [Net::HTTPGenericRequest] request to be done.
89
+ #
90
+ # == Returns:
91
+ # The response of this request.
92
+ def start_response(request, uri)
93
+ response = Net::HTTP.start(uri.hostname,
94
+ uri.port,
95
+ use_ssl: uri.scheme = 'https') do |http|
96
+ http.request(request)
97
+ end
98
+ http_error_handler(response)
99
+ response
100
+ end
101
+
102
+ # Sends a DELETE request to the specified URL.
103
+ #
104
+ # @param end_point_url [String] To be appended onto api_url to be used in the request.
105
+ #
106
+ # == Returns:
107
+ # A response object of the request.
108
+ def delete(end_point_url)
109
+ uri = URI(@api_url + end_point_url)
110
+ request = Net::HTTP::Delete.new(uri)
111
+ @headers.each_with_index do |(k, v)|
112
+ request[k] = v
113
+ end
114
+ request.basic_auth(@auth.credentials[0], @auth.credentials[1])
115
+ start_response(request, uri)
116
+ end
117
+
118
+ # Sends a GET request to the specified URL.
119
+ #
120
+ # @param end_point_url [String] To be appended onto api_url to be used in the request.
121
+ #
122
+ # == Returns:
123
+ # A response object of the request.
124
+ def get(end_point_url)
125
+ uri = URI(@api_url + end_point_url)
126
+ request = Net::HTTP::Get.new(uri)
127
+ @headers.each_with_index do |(k, v)|
128
+ request[k] = v
129
+ end
130
+ request.basic_auth(@auth.credentials[0], @auth.credentials[1])
131
+ start_response(request, uri)
132
+ end
133
+
134
+ # Sends a PATCH request to the specified URL.
135
+ #
136
+ # @param end_point_url [String] To be appended onto api_url to be used in the request.
137
+ # @param data Data object to be encoded into JSON. If not used, nothing is put in the body of the request.
138
+ #
139
+ # == Returns:
140
+ # A response object of the request.
141
+ def patch(end_point_url, data = nil)
142
+ uri = URI(@api_url + end_point_url)
143
+ request = Net::HTTP::Patch.new uri
144
+ @headers.each_with_index do |(k, v)|
145
+ request[k] = v
146
+ end
147
+ request.basic_auth(@auth.credentials[0], @auth.credentials[1])
148
+ request['Content-Type'] = 'application/json'
149
+ request.body = data.to_json if data
150
+ start_response(request, uri)
151
+ end
152
+
153
+ # Sends a POST request to the specified URL.
154
+ #
155
+ # @param end_point_url [String] To be appended onto api_url to be used in the request.
156
+ # @param data Data object to be encoded into JSON. If not used, nothing is put in the body of the request.
157
+ #
158
+ # == Returns:
159
+ # A response object of the request.
160
+ def post(end_point_url, data = nil)
161
+ uri = URI(@api_url + end_point_url)
162
+ request = Net::HTTP::Post.new uri
163
+ @headers.each_with_index do |(k, v)|
164
+ request[k] = v
165
+ end
166
+ request.basic_auth(@auth.credentials[0], @auth.credentials[1])
167
+ request['Content-Type'] = 'application/json'
168
+ request.body = data.to_json if data
169
+ start_response(request, uri)
170
+ end
171
+
172
+ # Sends a GET request to /whoami/.
173
+ #
174
+ # == Returns:
175
+ # An OpenStruct object of the response. The design of this Object will be the same as the ones on the PrintNode API docs.
176
+ # @see {https://www.printnode.com/docs/api/curl/#whoami Whoami on API Docs}
177
+ def whoami
178
+ OpenStruct.new JSON.parse(get('/whoami/').body)
179
+ end
180
+
181
+ # Sends a POST request to /account/.
182
+ #
183
+ # @param account [PrintNode::Account] Account object for new user.
184
+ # @option options [Array[String]] :ApiKeys Array of apikey descriptions to be created for this account.
185
+ # @option options [Hash] :Tags tag_name => tag_value hash of tags to be added for this user.
186
+ #
187
+ # == Returns:
188
+ # An OpenStruct object of the response. The design of this Object will be the same as the ones on the PrintNode API docs.
189
+ # @see http://www.printnode.com/docs/api/curl/#account-creation Account Creation on API Docs
190
+ def create_account(account, options = {})
191
+ hash = {}
192
+ hash['Account'] = account.to_hash
193
+ if options
194
+ options.each do |(k, v)|
195
+ hash[k] = v
196
+ end
197
+ end
198
+ response_object = JSON.parse(post('/account/', hash).body)
199
+ parse_hash_to_struct(response_object)
200
+ end
201
+
202
+ # Sends a PATCH request to /account/.
203
+ #
204
+ # @option options [String] :firstname new Firstname of user.
205
+ # @option options [String] :lastname new Last+']')[0]ions [String] :password new Password of user.
206
+ # @option options [String] :email new Email of user.
207
+ # @option options [String] :creatorRef new creator reference of user.
208
+ #
209
+ # == Returns:
210
+ # An OpenStruct object of the response. The design of this Object will be the same as the ones on the PrintNode API docs.
211
+ # @see http://www.printnode.com/docs/api/curl/#account-modification Account Modification on API Docs
212
+ def modify_account(options = {})
213
+ hash = options.dup
214
+ response_object = JSON.parse(patch('/account/', hash).body)
215
+ parse_hash_to_struct(response_object)
216
+ end
217
+
218
+ # Sends a DELETE request to /account/.
219
+ #
220
+ # == Returns:
221
+ # A boolean of whether the account was deleted or not.
222
+ def delete_account?
223
+ JSON.parse('[' + delete('/account/').body + ']')[0]
224
+ end
225
+
226
+ # Sends a GET request to /account/tag/(tag_name).
227
+ #
228
+ # @param tag_name [String] the name of the tag to be gotten.
229
+ #
230
+ # == Returns:
231
+ # A string which is the value of the tag requested.
232
+ def tags(tag_name)
233
+ end_point_url = '/account/tag/' + escape_with_types(tag_name)
234
+ JSON.parse('[' + get(end_point_url).body + ']')[0]
235
+ end
236
+
237
+ # Sends a POST request to /account/tag/(tag_name).
238
+ #
239
+ # @param tag_name [String] the name of the tag to be created.
240
+ # @param tag_value [String] the name of the tag value to be created.
241
+ # == Returns:
242
+ # If this creates a tag, a String 'created' will be returned. If it updates one, 'updated' will be returned.
243
+ def set_tag(tag_name, tag_value)
244
+ end_point_url = '/account/tag/' + escape_with_types(tag_name)
245
+ JSON.parse('[' + post(end_point_url, tag_value).body + ']')[0]
246
+ end
247
+
248
+ # Sends a DELETE request to /account/tag/(tag_name).
249
+ #
250
+ # == Returns:
251
+ # A boolean of whether the tag was deleted or not.
252
+ def delete_tag?(tag_name)
253
+ end_point_url = '/account/tag/' + escape_with_types(tag_name)
254
+ JSON.parse('[' + delete(end_point_url).body + ']')[0]
255
+ end
256
+
257
+ # Sends a GET request to /account/apikey/(description).
258
+ #
259
+ # @param description [String] Description of the API-Key to be gotten.
260
+ #
261
+ # == Returns:
262
+ # The API-Key itself.
263
+ def apikeys(description)
264
+ end_point_url = '/account/apikey/' + escape_with_types(description)
265
+ JSON.parse('[' + get(end_point_url).body + ']')[0]
266
+ end
267
+
268
+ # Sends a POST request to /account/apikey/(description).
269
+ #
270
+ # @param description [String] Description of the API-Key to be made.
271
+ #
272
+ # == Returns:
273
+ # The API-Key that was created.
274
+ def create_apikey(description)
275
+ end_point_url = '/account/apikey/' + escape_with_types(description)
276
+ JSON.parse('[' + post(end_point_url).body + ']')[0]
277
+ end
278
+
279
+ # Sends a DELETE request to /account/apikey/(description).
280
+ #
281
+ # @param description [String] Description of the API-Key to be deleted.
282
+ #
283
+ # == Returns:
284
+ # A boolean of whether the API-Key was deleted or not.
285
+ def delete_apikey?(description)
286
+ end_point_url = '/account/apikey/' + escape_with_types(description)
287
+ JSON.parse('[' + delete(end_point_url).body + ']')[0]
288
+ end
289
+
290
+ # Sends a GET request to /client/key/(uuid)?edition=(edition)&version=(version)
291
+ #
292
+ # @param uuid [String] the UUID of the client
293
+ # @param edition [String] the edition of the client
294
+ # @param version [String] The version of the client
295
+ #
296
+ # == Returns:
297
+ # The Client-key that was gotten.
298
+ def clientkeys(uuid, edition, version)
299
+ end_point_url = '/client/key/' +
300
+ escape_with_types(uuid) +
301
+ '?edition=' +
302
+ escape_with_types(edition) +
303
+ '&version=' +
304
+ escape_with_types(version)
305
+ JSON.parse('[' + get(end_point_url).body + ']')[0]
306
+ end
307
+
308
+ # Sends a GET request to /download/client/(os)
309
+ #
310
+ # @param os [String] the OS of the client to be found.
311
+ #
312
+ # == Returns:
313
+ # An OpenStruct object of the response. The design of this Object will be the same as the ones on the PrintNode API docs.
314
+ # @see https://www.printnode.com/docs/api/curl/#account-download-management Client Downloads on API Docs
315
+ def latest_client(os = 'windows')
316
+ end_point_url = '/download/client/' + escape_with_types(os.downcase)
317
+ OpenStruct.new JSON.parse(get(end_point_url).body)
318
+ end
319
+
320
+ # Sends a GET request to /download/clients/(client_set)
321
+ #
322
+ # @param client_set [String] a set of the clients to be got
323
+ #
324
+ # == Returns:
325
+ # An Array of OpenStruct objects. The design of this Object will be the same as the ones on the PrintNode API docs.
326
+ # @see https://www.printnode.com/docs/api/curl/#account-download-management Client Downloads on API Docs
327
+ def clients(client_set = '')
328
+ end_point_url = '/download/clients/' + escape_with_types(client_set)
329
+ response_object = JSON.parse(get(end_point_url).body)
330
+ parse_array_to_struct(response_object)
331
+ end
332
+
333
+ # Sends a PATCH request to /download/clients/(client_set)
334
+ #
335
+ # @param client_set [String] a set of have their settings changed
336
+ # @param enabled [Boolean] whether we want to enable (true) or disable (false) the clients.
337
+ #
338
+ # == Returns:
339
+ # An Array of ints that are ids that were changed.
340
+ def modify_client_downloads(client_set, enabled)
341
+ hash = { 'enabled' => enabled }
342
+ end_point_url = '/download/clients/' + escape_with_types(client_set)
343
+ JSON.parse(patch(end_point_url, hash).body)
344
+ end
345
+
346
+ # Sends a GET request to /computers/(computer_set)
347
+ #
348
+ # @param computer_set [String] a set of the computers to be got.
349
+ #
350
+ # == Returns:
351
+ # An Array of OpenStruct objects. The design of this Object will be the same as the ones on the PrintNode API docs.
352
+ # @see https://www.printnode.com/docs/api/curl/#computers Computers on API Docs
353
+ def computers(computer_set = '')
354
+ end_point_url = '/computers/' + escape_with_types(computer_set)
355
+ response_object = JSON.parse(get(end_point_url).body)
356
+ parse_array_to_struct(response_object)
357
+ end
358
+
359
+ def scales(computer_id)
360
+ end_point_url = '/computer/' +
361
+ escape_with_types(computer_id) +
362
+ '/scales/'
363
+ response_object = JSON.parse(get(end_point_url).body)
364
+ parse_array_to_struct(response_object)
365
+ end
366
+ # Sends a GET request to /printers/(set_a), or:
367
+ # /computers/(set_a)/printers/(set_b) if set_b is used.
368
+ #
369
+ # @param set_a [String] if set_b used: set of computers relative to printers set in set_b.
370
+ # if set_b unused: set of printers to be got.
371
+ #
372
+ # @param set_b [String] set of printers.
373
+ # == Returns:
374
+ # An Array of OpenStruct objects. The design of this Object will be the same as the ones on the PrintNode API docs.
375
+ # @see https://www.printnode.com/docs/api/curl/#printers Printers on API Docs
376
+ def printers(set_a = '', set_b = nil)
377
+ if set_b
378
+ end_point_url = '/computers/' +
379
+ escape_with_types(set_a) +
380
+ '/printers/' +
381
+ escape_with_types(set_b)
382
+ else
383
+ end_point_url = '/printers/' + escape_with_types(set_a)
384
+ end
385
+ response_object = JSON.parse(get(end_point_url).body)
386
+ parse_array_to_struct(response_object)
387
+ end
388
+
389
+ # Sends a GET request to /printjobs/(set_a), or:
390
+ # /printers/(set_a)/printjobs/(set_b) if set_b is used.
391
+ #
392
+ # @param set_a [String] if set_b used: set of printers relative to printjobs set in set_b.
393
+ # if set_b unused: set of printjobs to be got.
394
+ #
395
+ # @param set_b [String] set of printjobs.
396
+ # == Returns:
397
+ # An Array of OpenStruct objects. The design of this Object will be the same as the ones on the PrintNode API docs.
398
+ # @see https://www.printnode.com/docs/api/curl/#printjob-viewing PrintJobs on API Docs
399
+ def printjobs(set_a = '', set_b = nil)
400
+ if set_b
401
+ end_point_url = '/printers/' +
402
+ escape_with_types(set_a) +
403
+ '/printjobs/' +
404
+ escape_with_types(set_b)
405
+ else
406
+ end_point_url = '/printjobs/' + escape_with_types(set_a)
407
+ end
408
+ response_object = JSON.parse(get(end_point_url).body)
409
+ parse_array_to_struct(response_object)
410
+ end
411
+
412
+ # Sends a POST request to /printjobs/.
413
+ #
414
+ # @param printjob [PrintNode::PrintJob] printjob object to be submitted.
415
+ # @option options [Hash] :options a hash of any of the options available on the API docs.
416
+ # @option options [int] :expireAfter Number of seconds until printjob expires.
417
+ # @option options [int] :qty how many times this printjob will be sent to the server.
418
+ # @option options [Hash] :authentication A hash of an authentication object found on the API docs.
419
+ #
420
+ # == Returns:
421
+ # The id of the printjob that was created.
422
+ # @see https://www.printnode.com/docs/api/curl#printjob-creating PrintJob creating on API Docs
423
+ # @see https://www.printnode.com/docs/api/curl#printjob-options PrintJob options on API Docs
424
+ def create_printjob(printjob, options = {})
425
+ hash = printjob.to_hash
426
+ if options
427
+ options.each do |(k, v)|
428
+ hash[k] = v
429
+ end
430
+ end
431
+ JSON.parse('[' + post('/printjobs/', hash).body + ']')[0]
432
+ end
433
+
434
+ # sends a GET request to /printjobs/(printjob_set)/states
435
+ #
436
+ # @param printjob_set [String] set of printjobs that we will get states for.
437
+ #
438
+ # == Returns:
439
+ # An Array of OpenStruct objects. The design of this Object will be the same as the ones on the PrintNode API docs.
440
+ # @see https://www.printnode.com/docs/api/curl/#printjob-states PrintJob states on API Docs
441
+ def states(printjob_set = '')
442
+ if printjob_set == ''
443
+ end_point_url = '/printjobs/states/'
444
+ else
445
+ end_point_url = '/printjobs/' +
446
+ escape_with_types(printjob_set) +
447
+ '/states/'
448
+ end
449
+ response_object = JSON.parse(get(end_point_url).body)
450
+ parse_array_to_struct(response_object)
451
+ end
452
+
453
+ # Handles HTTP errors in the code.
454
+ # If the HTTP status code is not 2xx (OK), it will raise an error.
455
+ #
456
+ # @param response [Net::HTTPResponse] A response from any of the request methods.
457
+ def http_error_handler(response)
458
+ begin
459
+ unless response.code.to_s.match('^2..')
460
+ fail APIError.new(response.code), response.body
461
+ end
462
+ rescue APIError => e
463
+ puts 'HTTP Error found: ' + e.object
464
+ puts 'This was the body of the response: '
465
+ puts e.message
466
+ end
467
+ end
468
+ end
469
+ end
@@ -0,0 +1,32 @@
1
+ require 'base64'
2
+ module PrintNode
3
+ class PrintJob
4
+ attr_accessor :printer_id
5
+ attr_accessor :title
6
+ attr_accessor :content_type
7
+ attr_accessor :content
8
+ attr_accessor :source
9
+
10
+ def to_hash
11
+ hash = {}
12
+ hash['printerId'] = @printer_id
13
+ hash['title'] = @title
14
+ hash['contentType'] = @content_type
15
+ if @content_type.match('base64$')
16
+ hash ['content'] = base64.encode(IO.read(@content))
17
+ else
18
+ hash ['content'] = @content
19
+ end
20
+ hash['source'] = @source
21
+ hash
22
+ end
23
+
24
+ def initialize(printer_id, title, content_type, content, source)
25
+ @printer_id = printer_id
26
+ @title = title
27
+ @content_type = content_type
28
+ @content = content
29
+ @source = source
30
+ end
31
+ end
32
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: printnode
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - PrintNode
8
+ - Jake Torrance
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-07-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: test-unit
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ description: Ruby API Library for PrintNode remote printing service.
43
+ email:
44
+ - support@printnode.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - lib/printnode.rb
50
+ - lib/printnode/account.rb
51
+ - lib/printnode/api_exception.rb
52
+ - lib/printnode/auth.rb
53
+ - lib/printnode/client.rb
54
+ - lib/printnode/printjob.rb
55
+ homepage: https://www.printnode.com
56
+ licenses:
57
+ - MIT
58
+ metadata: {}
59
+ post_install_message: Happy Printing!
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 2.2.2
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: PrintNode-Ruby
79
+ test_files: []
80
+ has_rdoc: