boxview.rb 0.0.9
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 +7 -0
- data/.gitignore +22 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +17 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +268 -0
- data/Rakefile +7 -0
- data/boxview.rb.gemspec +26 -0
- data/lib/boxview.rb +56 -0
- data/lib/boxview/document.rb +364 -0
- data/lib/boxview/errors.rb +147 -0
- data/lib/boxview/session.rb +144 -0
- data/lib/boxview/version.rb +3 -0
- data/spec/lib/boxview/document_spec.rb +87 -0
- data/spec/lib/boxview/errors_spec.rb +5 -0
- data/spec/lib/boxview/session_spec.rb +29 -0
- data/spec/lib/boxview/version_spec.rb +11 -0
- data/spec/lib/boxview_spec.rb +28 -0
- data/spec/spec_helper.rb +5 -0
- metadata +127 -0
@@ -0,0 +1,364 @@
|
|
1
|
+
module BoxView
|
2
|
+
class Document
|
3
|
+
|
4
|
+
# ToDo: Investigate https://github.com/jwagener/httmultiparty
|
5
|
+
# For multi part upload support
|
6
|
+
|
7
|
+
PATH = '/documents'
|
8
|
+
ZIP = 'zip' # Constant for generating a zip of assets of a document
|
9
|
+
PDF = 'pdf' # Constant for generating a pdf of a document
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
attr_accessor :url, :name, :non_svg, :type, :width, :height, :retry_after, :filepath
|
14
|
+
|
15
|
+
# Description:
|
16
|
+
# => The getter method for the url of a box view compatible file. Look at supported_mimetypes.
|
17
|
+
# No Params!
|
18
|
+
# Note:
|
19
|
+
# => Raises an error if the url is nil.
|
20
|
+
def url
|
21
|
+
raise BoxView::Errors::UrlNotFound if @url.nil?
|
22
|
+
@url
|
23
|
+
end
|
24
|
+
|
25
|
+
# Description:
|
26
|
+
# => The getter method for the filepath of a box view compatible file. Look at supported_mimetypes.
|
27
|
+
# No Params!
|
28
|
+
# Note:
|
29
|
+
# => Raises an error if the filepath is nil or does not exist.
|
30
|
+
def filepath
|
31
|
+
raise BoxView::Errors::FilepathNotFound if @filepath.nil? || !File.file?(@filepath)
|
32
|
+
@filepath
|
33
|
+
end
|
34
|
+
|
35
|
+
# Description:
|
36
|
+
# => The setter method for the type of asset to be downloaded.
|
37
|
+
# Required Params:
|
38
|
+
# => type
|
39
|
+
# Note:
|
40
|
+
# => This method only accepts pdf or zip as types.
|
41
|
+
def type=(type)
|
42
|
+
raise BoxView::Errors::TypeNotFound if ![ZIP, PDF].include? type.downcase
|
43
|
+
@type = type
|
44
|
+
end
|
45
|
+
|
46
|
+
#########################################################
|
47
|
+
|
48
|
+
### BEGIN Document HTTP Requests ###
|
49
|
+
|
50
|
+
# Description:
|
51
|
+
# => Sends a document url (and other metadata) for Box to download
|
52
|
+
# Required Paramaters:
|
53
|
+
# => URL: Url of the file to convert. (.pdf, .doc, .docx, .ppt, and .pptx)
|
54
|
+
# Optional Paramaters:
|
55
|
+
# => name: Name of the document.
|
56
|
+
# => non_svg: false by default, enable to support < IE9 browsers
|
57
|
+
# => width: width of a thumbnail that will be generated from this document (16-1024)
|
58
|
+
# => height: height of a thumbnail that will be generated from this document (16-768)
|
59
|
+
# Note:
|
60
|
+
# => The params may be passed in when calling the function or defined before hand.
|
61
|
+
def create(options = {})
|
62
|
+
response = BoxView.post document_path, body: json_data(options), headers: BoxView.headers
|
63
|
+
create_response_handler response
|
64
|
+
return response
|
65
|
+
end
|
66
|
+
|
67
|
+
# Description:
|
68
|
+
# => Allows metadata, specifically the name of a document to be updated. Requires a document id.
|
69
|
+
# Optional Params:
|
70
|
+
# => Name, Document ID
|
71
|
+
def update(options = {})
|
72
|
+
name = options[:name] if options[:name]
|
73
|
+
BoxView.document_id = options[:document_id] if options[:document_id]
|
74
|
+
response = BoxView.put document_path, body: {name: name}.to_json, headers: BoxView.headers
|
75
|
+
update_response_handler response
|
76
|
+
return response
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# Description:
|
81
|
+
# => Uses https://github.com/jwagener/httmultiparty for multipart uploading while still using HTTParty
|
82
|
+
# No Params!
|
83
|
+
def multipart(options = {})
|
84
|
+
BoxView.base_uri BoxView::MULTIPART_URI
|
85
|
+
(multipart_headers = BoxView.headers).delete('Content-type')
|
86
|
+
response = BoxView.post document_path, body: multipart_data(options), headers: multipart_headers, detect_mime_type: true
|
87
|
+
multipart_response_handler response
|
88
|
+
return response
|
89
|
+
end
|
90
|
+
|
91
|
+
# Description:
|
92
|
+
# => This request will list all the current documents that were uploaded to box view by api key.
|
93
|
+
# No Params!
|
94
|
+
def list
|
95
|
+
response = BoxView.get document_path, headers: BoxView.headers
|
96
|
+
list_response_handler response
|
97
|
+
return response
|
98
|
+
end
|
99
|
+
|
100
|
+
# Description:
|
101
|
+
# => Returns the box view object for a specific document. Requires a document id.
|
102
|
+
# No Params!
|
103
|
+
def show(options = {})
|
104
|
+
BoxView.document_id = options[:document_id] if options[:document_id]
|
105
|
+
response = BoxView.get "#{document_path}/#{BoxView.document_id}", headers: BoxView.headers
|
106
|
+
show_response_handler response
|
107
|
+
return response
|
108
|
+
end
|
109
|
+
|
110
|
+
# Description:
|
111
|
+
# => Delete a document from box view given a document id.
|
112
|
+
# No Required Params!
|
113
|
+
# Optional Params:
|
114
|
+
# => Document ID
|
115
|
+
def delete(options = {})
|
116
|
+
BoxView.document_id = options[:document_id] if options[:document_id]
|
117
|
+
response = BoxView.delete "#{document_path}/#{BoxView.document_id}", headers: BoxView.headers
|
118
|
+
delete_response_handler response
|
119
|
+
return response
|
120
|
+
end
|
121
|
+
|
122
|
+
# Description:
|
123
|
+
# =>
|
124
|
+
# No Params!
|
125
|
+
# Description:
|
126
|
+
# => Returns a pdf or zip representation of a document that has previously been uploaded to box view. Requires a document id.
|
127
|
+
# No Required Params!
|
128
|
+
# Optional Params:
|
129
|
+
# => Type, Document ID
|
130
|
+
def assets(options = {})
|
131
|
+
BoxView.document_id = options[:document_id] if options[:document_id]
|
132
|
+
type = options[:type] if options[:type]
|
133
|
+
response = BoxView.get asset_url, headers: BoxView.headers
|
134
|
+
asset_response_handler response
|
135
|
+
return response
|
136
|
+
end
|
137
|
+
|
138
|
+
# Description:
|
139
|
+
# => Returns a thumbnail image representation of a document that has previously been uploaded to box view. Requires a document id.
|
140
|
+
# => Inform BoxView early by specifying width and height when creating the document.
|
141
|
+
# No Required Params!
|
142
|
+
# Optional Params:
|
143
|
+
# => Width, Height, Document ID
|
144
|
+
def thumbnail(options = {})
|
145
|
+
BoxView.document_id = options[:document_id] if options[:document_id]
|
146
|
+
width = options[:width] if options[:width]
|
147
|
+
height = options[:height] if options[:height]
|
148
|
+
response = BoxView.get thumbnail_url, headers: BoxView.headers
|
149
|
+
thumbnail_response_handler response
|
150
|
+
return response
|
151
|
+
end
|
152
|
+
|
153
|
+
### END Document HTTP Requests ###
|
154
|
+
|
155
|
+
# Description:
|
156
|
+
# => A path that is used for all document related requests.
|
157
|
+
# No Params!
|
158
|
+
def document_path
|
159
|
+
"#{BoxView::BASE_PATH}#{PATH}"
|
160
|
+
end
|
161
|
+
|
162
|
+
# Description:
|
163
|
+
# => A convenience method that contains all of the supported mimetypes of Box View.
|
164
|
+
# No Params!
|
165
|
+
def supported_mimetypes
|
166
|
+
[ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
167
|
+
"application/vnd.openxmlformats-officedocument.presentationml.slideshow",
|
168
|
+
"application/vnd.ms-powerpoint",
|
169
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
170
|
+
"application/msword",
|
171
|
+
"application/pdf"
|
172
|
+
]
|
173
|
+
end
|
174
|
+
|
175
|
+
# Description:
|
176
|
+
# => A convenience method that contains all the supported extension types of Box View
|
177
|
+
# No Params!
|
178
|
+
def supported_file_extensions
|
179
|
+
['.pdf', '.doc', '.docx', '.ppt', '.pptx']
|
180
|
+
end
|
181
|
+
|
182
|
+
# Description:
|
183
|
+
# => The asset url that is used in the request for document assets.
|
184
|
+
# No Params!
|
185
|
+
# Note:
|
186
|
+
# => Type defaults to zip if not defined.
|
187
|
+
# => A Document ID must be defined.
|
188
|
+
def asset_url
|
189
|
+
type = if @type then @type else ZIP end # Defaults to ZIP
|
190
|
+
"#{document_path}/#{BoxView.document_id}/content.#{type}"
|
191
|
+
end
|
192
|
+
|
193
|
+
# Description: Params for retrieving a thumbnail of a certain size
|
194
|
+
# => Minimum Width and Height is 16
|
195
|
+
# => Maximum Width is 1024
|
196
|
+
# => Maximum Height is 768
|
197
|
+
# No Params!
|
198
|
+
# Note: Height and Width MUST be defined.
|
199
|
+
def thumbnail_params
|
200
|
+
raise BoxView::Errors::DimensionsNotFound if width.nil? || height.nil?
|
201
|
+
"?width=#{width}&height=#{height}"
|
202
|
+
end
|
203
|
+
|
204
|
+
# Description:
|
205
|
+
# =>
|
206
|
+
# No Params!
|
207
|
+
def dimensions
|
208
|
+
raise BoxView::Errors::DimensionsNotFound if width.nil? || height.nil?
|
209
|
+
"#{width}x#{height}"
|
210
|
+
end
|
211
|
+
|
212
|
+
# Description:
|
213
|
+
# => Path to request thumbnail generation for a specific document. Requires document id, width and height.
|
214
|
+
# No Params!
|
215
|
+
def thumbnail_url
|
216
|
+
"#{document_path}/#{BoxView.document_id}/thumbnail#{thumbnail_params}"
|
217
|
+
end
|
218
|
+
|
219
|
+
private
|
220
|
+
|
221
|
+
# Description:
|
222
|
+
# => Response Handler for the thumbnail request
|
223
|
+
# Required Params:
|
224
|
+
# => response
|
225
|
+
def thumbnail_response_handler(response)
|
226
|
+
case response.code
|
227
|
+
when 200 # Valid thumbnail
|
228
|
+
when 202 # Thumbnail isn't ready yet
|
229
|
+
retry_after = response['Retry-After']
|
230
|
+
when 400 # Width/Height are invalid
|
231
|
+
raise BoxView::Errors::ThumbnailInvalidWidthHeight
|
232
|
+
else
|
233
|
+
raise BoxView::Errors::ThumbnailGenerationFailed
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Description:
|
238
|
+
# => Response Handler for the delete request
|
239
|
+
# Required Params:
|
240
|
+
# => response
|
241
|
+
def delete_response_handler(response)
|
242
|
+
case response.code
|
243
|
+
when 200
|
244
|
+
else
|
245
|
+
raise BoxView::Errors::DocumentDeletionFailed.new(response)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
# Description:
|
250
|
+
# => Response Handler for the asset request
|
251
|
+
# Required Params:
|
252
|
+
# => response
|
253
|
+
def asset_response_handler(response)
|
254
|
+
case response.code
|
255
|
+
when 200
|
256
|
+
else
|
257
|
+
raise BoxView::Errors::AssetGeneratioFailed.new(response)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Description:
|
262
|
+
# => Response Handler for the show request
|
263
|
+
# Required Params:
|
264
|
+
# => response
|
265
|
+
def show_response_handler(response)
|
266
|
+
case response.code
|
267
|
+
when 200
|
268
|
+
else
|
269
|
+
raise BoxView::Errors::DocumentFetchFailed.new(response)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# Description:
|
274
|
+
# => Response Handler for the list request
|
275
|
+
# Required Params:
|
276
|
+
# => response
|
277
|
+
def list_response_handler(response)
|
278
|
+
case response.code
|
279
|
+
when 200
|
280
|
+
else
|
281
|
+
raise BoxView::Errors::DocumentListFetchFailed.new(response)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# Description:
|
286
|
+
# => Response Handler for the create request
|
287
|
+
# Required Params:
|
288
|
+
# => response
|
289
|
+
def create_response_handler(response)
|
290
|
+
if (200..202).include? response.code
|
291
|
+
parsed = JSON.parse response.body
|
292
|
+
document_id = parsed["id"]
|
293
|
+
BoxView.document_id = document_id
|
294
|
+
else
|
295
|
+
raise BoxView::Errors::DocumentIdNotGenerated.new(response)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# Description:
|
300
|
+
# => Response Handler for the update request
|
301
|
+
# Required Params:
|
302
|
+
# => response
|
303
|
+
def update_response_handler(response)
|
304
|
+
if (200..202).include? response.code
|
305
|
+
parsed = JSON.parse response.body
|
306
|
+
document_id = parsed["id"]
|
307
|
+
BoxView.document_id = document_id
|
308
|
+
else
|
309
|
+
raise BoxView::Errors::DocumentNotUpdated.new(response)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# Description:
|
314
|
+
# => Response Handler for the multipart request
|
315
|
+
# Required Params:
|
316
|
+
# => response
|
317
|
+
def multipart_response_handler(response)
|
318
|
+
BoxView.base_uri BoxView::BASE_URI # restores original base_uri
|
319
|
+
if (200..202).include? response.code
|
320
|
+
parsed = JSON.parse response.body
|
321
|
+
document_id = parsed["id"]
|
322
|
+
BoxView.document_id = document_id
|
323
|
+
else
|
324
|
+
raise BoxView::Errors::DocumentNotUpdated.new(response)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
# Description:
|
329
|
+
# => The JSON that is sent in document creation requests.
|
330
|
+
# No Required Params!
|
331
|
+
# Optional Params:
|
332
|
+
# => URL, Name, Width, Height, non_svg
|
333
|
+
def json_data(options = {})
|
334
|
+
options.each do |k,v|
|
335
|
+
send "#{k}=", v if v
|
336
|
+
end
|
337
|
+
data = {}
|
338
|
+
data[:url] = url
|
339
|
+
data[:name] = name if name
|
340
|
+
data[:thumbnails] = dimensions if width && height
|
341
|
+
data[:non_svg] = non_svg if non_svg
|
342
|
+
return data.to_json
|
343
|
+
end
|
344
|
+
|
345
|
+
# Description:
|
346
|
+
# => The hash that is sent in document multipart requests.
|
347
|
+
# No Required Params!
|
348
|
+
# Optional Params:
|
349
|
+
# => Filepath, Name, Width, Height, non_svg
|
350
|
+
def multipart_data(options = {})
|
351
|
+
options.each do |k,v|
|
352
|
+
send "#{k}=", v if v
|
353
|
+
end
|
354
|
+
data = {}
|
355
|
+
data[:file] = File.new(filepath, 'r') if filepath
|
356
|
+
data[:name] = name if name
|
357
|
+
data[:thumbnails] = dimensions if width && height
|
358
|
+
data[:non_svg] = non_svg if non_svg
|
359
|
+
return data
|
360
|
+
end
|
361
|
+
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module BoxView
|
2
|
+
class Errors < StandardError
|
3
|
+
|
4
|
+
def initialize(message, error = nil)
|
5
|
+
# super message
|
6
|
+
if error.nil?
|
7
|
+
super message
|
8
|
+
else
|
9
|
+
case error
|
10
|
+
when 400 then super "#{message} - Error Code: 400 - Document does not exist or failed converting."
|
11
|
+
else super message
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class DocumentNotUpdated < StandardError
|
17
|
+
DOCUMENT_UPDATE_ERROR_MESSAGE = "The document failed to update."
|
18
|
+
def initialize(response = nil)
|
19
|
+
super "#{DOCUMENT_UPDATE_ERROR_MESSAGE} - with ID: #{BoxView.document_id} - Response Code: #{response.code}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class AssetGenerationFailed < StandardError
|
24
|
+
ASSET_GENERATION_ERROR_MESSAGE = "The assets failed to generate."
|
25
|
+
def initialize(response = nil)
|
26
|
+
super "#{ASSET_GENERATION_ERROR_MESSAGE} - with ID: #{BoxView.document_id} - Response Code: #{response.code}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class DocumentListFetchFailed < StandardError
|
31
|
+
DOCUMENT_LIST_ERROR_MESSAGE = "Could not fetch document list."
|
32
|
+
def initialize(response = nil)
|
33
|
+
super "#{DOCUMENT_LIST_ERROR_MESSAGE} - Response Code: #{response.code}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class DocumentDeletionFailed < StandardError
|
38
|
+
DOCUMENT_DELETE_ERROR_MESSAGE = "Could not delete document."
|
39
|
+
def initialize(response = nil)
|
40
|
+
super "#{DOCUMENT_DELETE_ERROR_MESSAGE} - Response Code: #{response.code}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class DocumentFetchFailed < StandardError
|
45
|
+
DOCUMENT_ERROR_MESSAGE = "Could not fetch document."
|
46
|
+
def initialize(response = nil)
|
47
|
+
super "#{DOCUMENT_ERROR_MESSAGE} - with ID: #{BoxView.document_id} - Response Code: #{response.code}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class DocumentIdNotGenerated < StandardError
|
52
|
+
DOCUMENT_ID_ERROR_MESSAGE = "The document id has failed to be generated."
|
53
|
+
def initialize(response = nil)
|
54
|
+
if response
|
55
|
+
super "#{DOCUMENT_ID_ERROR_MESSAGE} - Response Code: #{response.code}"
|
56
|
+
else
|
57
|
+
super DOCUMENT_ID_ERROR_MESSAGE
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class DocumentConversionFailed < StandardError
|
63
|
+
CONVERSION_ERROR_MESSAGE = "Converting the document has failed."
|
64
|
+
def initialize
|
65
|
+
super CONVERSION_ERROR_MESSAGE
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class SessionNotGenerated < StandardError
|
70
|
+
GENERATION_ERROR_MESSAGE = "Session could not be generated."
|
71
|
+
def initialize
|
72
|
+
super GENERATION_ERROR_MESSAGE
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class ThumbnailGenerationFailed < StandardError
|
77
|
+
GENERATION_ERROR_MESSAGE = "Thumbnail could not be generated."
|
78
|
+
def initialize
|
79
|
+
super GENERATION_ERROR_MESSAGE
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class ThumbnailInvalidWidthHeight < StandardError
|
84
|
+
WIDTH_HEIGHT_ERROR_MESSAGE = "The thumbnails width or height is invalid."
|
85
|
+
def initialize
|
86
|
+
super WIDTH_HEIGHT_ERROR_MESSAGE
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class ApiKeyNotFound < StandardError
|
91
|
+
API_KEY_ERROR_MESSAGE = "API Key is nil." # test to make sure it is string, digits and alphanumeric, correct length?
|
92
|
+
def initialize
|
93
|
+
super API_KEY_ERROR_MESSAGE
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class DimensionsNotFound < StandardError
|
98
|
+
DIMENSIONS_ERROR_MESSAGE = "Height and Width must both be specified."
|
99
|
+
def initialize
|
100
|
+
super DIMENSIONS_ERROR_MESSAGE
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class DocumentIdNotFound < StandardError
|
105
|
+
DOCUMENT_ID_ERROR_MESSAGE = "Document ID must be specified."
|
106
|
+
def initialize
|
107
|
+
super DOCUMENT_ID_ERROR_MESSAGE
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class ExpirationDateNotFound < StandardError
|
112
|
+
EXPIRATION_DATE_ERROR_MESSAGE = "An Expiration Date must be specified."
|
113
|
+
def initialize
|
114
|
+
super EXPIRATION_DATE_ERROR_MESSAGE
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class DurationNotFound < StandardError
|
119
|
+
DURATION_ERROR_MESSAGE = "A Duration must be specified."
|
120
|
+
def initialize
|
121
|
+
super DURATION_ERROR_MESSAGE
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
class SessionIdNotFound < StandardError
|
126
|
+
SESSION_ID_ERROR_MESSAGE = "A Session ID must be specified."
|
127
|
+
def initialize
|
128
|
+
super SESSION_ID_ERROR_MESSAGE
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class TypeNotFound < StandardError
|
133
|
+
TYPE_ERROR_MESSAGE = "A type must be specified."
|
134
|
+
def initialize
|
135
|
+
super TYPE_ERROR_MESSAGE
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class UrlNotFound < StandardError
|
140
|
+
URL_ERROR_MESSAGE = "A url must be specified."
|
141
|
+
def initialize
|
142
|
+
super URL_ERROR_MESSAGE
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|