everybit 0.1.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.
data/lib/everybit.rb ADDED
@@ -0,0 +1,78 @@
1
+ # Everybit Ruby Library
2
+ # API docs at http://dev.everybit.co
3
+
4
+ require 'rest_client'
5
+ require 'multi_json'
6
+
7
+ # version
8
+ require 'everybit/version'
9
+
10
+ # restful modules
11
+ require 'everybit/modules/listable'
12
+ require 'everybit/modules/deleteable'
13
+ require 'everybit/modules/createable'
14
+ require 'everybit/modules/updateable'
15
+
16
+ # resources
17
+ require 'everybit/everybit_object'
18
+ require 'everybit/resource'
19
+ require 'everybit/collection'
20
+ require 'everybit/account'
21
+ require 'everybit/video'
22
+
23
+ # Errors
24
+ require 'everybit/errors/everybit_error'
25
+ require 'everybit/errors/authentication_error'
26
+
27
+ module Everybit
28
+ @@api_key = nil
29
+ @@api_base = 'https://api.everybit.co'
30
+
31
+ def self.api_url(url='')
32
+ api_base + url
33
+ end
34
+
35
+ def self.api_key=(api_key)
36
+ @@api_key = api_key
37
+ end
38
+
39
+ def self.api_key
40
+ @@api_key
41
+ end
42
+
43
+ def self.api_base=(api_base)
44
+ @@api_base = api_base
45
+ end
46
+
47
+ def self.api_base
48
+ @@api_base
49
+ end
50
+
51
+ def self.request(method, url, params={}, headers={})
52
+ # we can't do anything without an api key, so bail early
53
+ raise AuthenticationError.new('No API key provided (set API key using "Everybit.api_key = API_KEY")') unless self.api_key
54
+
55
+ # prepare headers
56
+ headers = {
57
+ :user_agent => "everybit-ruby/#{Everybit::VERSION}",
58
+ 'x-apikey' => self.api_key
59
+ }.merge(headers)
60
+
61
+ # assemble all the options for the request
62
+ opts = {
63
+ method: method,
64
+ url: self.api_url(url),
65
+ headers: headers,
66
+ payload: MultiJson.dump(params)
67
+ }
68
+
69
+ # execute request
70
+ MultiJson.load(send_request(opts), symbolize_keys: true)
71
+ end
72
+
73
+ private
74
+
75
+ def self.send_request(opts)
76
+ RestClient::Request.execute(opts)
77
+ end
78
+ end
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ # this file contains all the tests related to
5
+ # requesting account details from the Everybit api
6
+
7
+ describe Everybit, 'Account Specs' do
8
+
9
+ before do
10
+ Everybit.api_key = '1a2b3c4d5e6f7g8h9i'
11
+ @params = {mock_response: 'mock_account'}
12
+ end
13
+
14
+ after do
15
+ Everybit.api_key = nil
16
+ end
17
+
18
+ it 'should wrap the response in an Everybit::Account object' do
19
+ Everybit::Account.retrieve(@params).must_be_instance_of Everybit::Account
20
+ end
21
+
22
+ it 'should create the correct url' do
23
+ res = Everybit::Account.retrieve(@params)
24
+ res[:opts][:url].must_equal 'https://api.everybit.co/v1/account'
25
+ end
26
+
27
+ it 'should create a code attribute' do
28
+ res = Everybit::Account.retrieve(@params)
29
+ res.code.must_equal 200
30
+ end
31
+
32
+ it 'should create a status attribute' do
33
+ res = Everybit::Account.retrieve(@params)
34
+ res.status.must_equal true
35
+ end
36
+
37
+ it 'should expose returned data' do
38
+ res = Everybit::Account.retrieve(@params)
39
+ res[:uuid].must_equal '787c8956-1857-4771-9d4e-b99b4dedfeae'
40
+ res[:email].must_equal 'jsmith@example.com'
41
+ res[:username].must_equal 'jsmith'
42
+ res[:first_name].must_equal 'John'
43
+ res[:last_name].must_equal 'Smith'
44
+ end
45
+
46
+ end # Account Specs
data/spec/misc_spec.rb ADDED
@@ -0,0 +1,49 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+
4
+ # this file contains all the miscellaneous tests
5
+ # that don't fit nicely into any other category
6
+
7
+ describe Everybit, 'Miscellaneous Specs' do
8
+
9
+ describe 'module level variables and instance methods' do
10
+
11
+ before do
12
+ @default_base_url = 'https://api.everybit.co'
13
+ end
14
+
15
+ it 'should have no api key by default' do
16
+ Everybit.api_key.must_be_nil
17
+ end
18
+
19
+ it 'should accept a new api key' do
20
+ Everybit.api_key = '1a2b3c4d5e6f7g8h9'
21
+ Everybit.api_key.must_equal '1a2b3c4d5e6f7g8h9'
22
+ Everybit.api_key = nil
23
+ end
24
+
25
+ it 'should have a default base api url' do
26
+ Everybit.api_base.must_equal @default_base_url
27
+ end
28
+
29
+ it 'should accept a new base api url' do
30
+ Everybit.api_base = 'http://staging.api.everybit.co'
31
+ Everybit.api_base.must_equal 'http://staging.api.everybit.co'
32
+ Everybit.api_base = @default_base_url
33
+ end
34
+
35
+ it 'should build a url using the base api url' do
36
+ Everybit.api_url.must_equal @default_base_url
37
+ Everybit.api_url('/media').must_equal @default_base_url + '/media'
38
+ end
39
+
40
+ it 'should require an api key when calling request()' do
41
+ Everybit.api_key = nil
42
+ assert_raises Everybit::AuthenticationError do
43
+ Everybit.request(:get, '/media')
44
+ end
45
+ end
46
+
47
+ end # module level variables and instance methods
48
+
49
+ end # Miscellaneous Specs
@@ -0,0 +1,277 @@
1
+ # -*- coding: utf-8 -*-
2
+ # use minitest gem, not the one from stdlib
3
+ gem 'minitest'
4
+
5
+ require 'minitest/autorun'
6
+ require 'turn'
7
+ require 'everybit'
8
+
9
+ # override the request method so it returns
10
+ # mock responses during testing
11
+ module Everybit
12
+ def self.send_request(opts)
13
+ payload = MultiJson.load(opts[:payload], symbolize_keys: true)
14
+ res = send(payload[:mock_response], opts)
15
+ MultiJson.dump(res)
16
+ end
17
+ end
18
+
19
+ def mock_account(opts={})
20
+ {
21
+ code: 200,
22
+ status: true,
23
+ data: {
24
+ opts: opts,
25
+ uuid: '787c8956-1857-4771-9d4e-b99b4dedfeae',
26
+ email: 'jsmith@example.com',
27
+ username: 'jsmith',
28
+ first_name: 'John',
29
+ last_name: 'Smith'
30
+ }
31
+ }
32
+ end
33
+
34
+ def mock_all_videos(opts={})
35
+ videos = mock_video_details(opts)
36
+ video = videos[:data]
37
+ {
38
+ code: 200,
39
+ status: true,
40
+ data: [video, video, video]
41
+ }
42
+ end
43
+
44
+ def mock_video_details(opts={})
45
+ {
46
+ code: 200,
47
+ status: true,
48
+ data: {
49
+ opts: opts,
50
+ uuid: '787c8956-1857-4771-9d4e-b99b4dedfeae',
51
+ owner_uuid: '787c8956-1857-4771-9d4e-b99b4dedfeae',
52
+ created_date: '1234567890',
53
+ last_updated: '1234567890',
54
+ visibility: 'private',
55
+ title: 'Video Title',
56
+ summary: 'A short description about the media.',
57
+ duration: 45347,
58
+ type: 'video',
59
+ source_url: 'http://static.everybit.co/787c8956-1857-4771-9d4e-b99b4dedfeae.mov',
60
+ player_url: 'http://static.everybit.co/player/787c8956-1857-4771-9d4e-b99b4dedfeae',
61
+ thumbnail: 'http://static.everybit.co/PATH_TO_FILE',
62
+ lat: '45.4535345',
63
+ lon: '32.3245344',
64
+ play_count: false,
65
+ data_consumed: 100,
66
+ player_attributes: mock_video_player_attributes,
67
+ media_info: mock_video_media_info,
68
+ versions: [
69
+ mock_video_versions,
70
+ mock_video_versions,
71
+ mock_video_versions,
72
+ mock_video_versions,
73
+ mock_video_versions,
74
+ mock_video_versions,
75
+ mock_video_versions,
76
+ mock_video_versions
77
+ ]
78
+ }
79
+ }
80
+ end
81
+
82
+ def mock_video_status(opts={})
83
+ {
84
+ code: 200,
85
+ status: true,
86
+ data: {
87
+ opts: opts,
88
+ uuid: '787c8956-1857-4771-9d4e-b99b4dedfeae',
89
+ processing: true,
90
+ progress: 50,
91
+ completed: false,
92
+ completed_date: nil
93
+ }
94
+ }
95
+ end
96
+
97
+ def mock_create_video_success(opts={})
98
+ {
99
+ code: 200,
100
+ status: true,
101
+ data: {
102
+ uuid: '787c8956-1857-4771-9d4e-b99b4dedfeae',
103
+ opts: opts
104
+ }
105
+ }
106
+ end
107
+
108
+ def mock_create_video_error(opts={})
109
+ {
110
+ code: 200,
111
+ status: false,
112
+ data: {
113
+ opts: opts,
114
+ error: 'some error message here'
115
+ }
116
+ }
117
+ end
118
+
119
+ def mock_delete_video_success(opts={})
120
+ {
121
+ code: 200,
122
+ status: true,
123
+ data: {
124
+ opts: opts,
125
+ message: 'your video was deleted successfully'
126
+ }
127
+ }
128
+ end
129
+
130
+ def mock_delete_video_error(opts={})
131
+ {
132
+ code: 200,
133
+ status: false,
134
+ data: {
135
+ opts: opts,
136
+ error: 'some error message here'
137
+ }
138
+ }
139
+ end
140
+
141
+ def mock_update_video_success(opts={})
142
+ {
143
+ code: 200,
144
+ status: true,
145
+ data: {
146
+ opts: opts,
147
+ message: 'your video was updated successfully'
148
+ }
149
+ }
150
+ end
151
+
152
+ def mock_update_video_error(opts={})
153
+ {
154
+ code: 200,
155
+ status: false,
156
+ data: {
157
+ opts: opts,
158
+ error: 'some error message here'
159
+ }
160
+ }
161
+ end
162
+
163
+ private
164
+
165
+ # mock video details versions response
166
+ def mock_video_versions
167
+ {
168
+ name: 'medium',
169
+ type: 'video/mp4',
170
+ rtmpStream: 'rtmp://static.everybit.co/PATH_TO_FILE',
171
+ httpStream: 'http://static.everybit.co:1935/PATH_TO_FILE',
172
+ rtspStream: 'rtsp://static.everybit.co:1935/PATH_TO_FILE',
173
+ progressiveDownload: 'http://static.everybit.co/PATH_TO_FILE'
174
+ }
175
+ end
176
+
177
+ # mock video details media info response
178
+ def mock_video_media_info
179
+ {
180
+ container: 'MPEG-4',
181
+ format_profile: 'QuickTime',
182
+ codec_id: 'qt',
183
+ file_size: 9466208,
184
+ duration: 4903,
185
+ overall_bit_rate: 16252928,
186
+ encoded_date: '2011-08-31 18:34:30',
187
+ tagged_date: '2011-08-31 18:34:30',
188
+ writing_library: 'Apple QuickTime',
189
+ video_format: 'AVC',
190
+ video_format_info: 'Advanced Video Codec',
191
+ video_format_profile: 'Main@L4.0',
192
+ video_format_settings_c_a_b_a_c: 'true',
193
+ video_format_settings_re_frames: '2 frames',
194
+ video_codec_id: 'avc1',
195
+ video_codec_id_info: 'Advanced Video Coding',
196
+ video_duration: 4903,
197
+ video_bit_rate: 14575206.4,
198
+ video_width: 1920,
199
+ video_height: 1080,
200
+ video_display_aspect_ratio: '16:9',
201
+ video_frame_rate_mode: 'Constant',
202
+ video_frame_rate: 29.970,
203
+ video_color_space: 'YUV',
204
+ video_chroma_subsampling: '4:2:0',
205
+ video_bit_depth: 8,
206
+ video_scan_type: 'Progressive',
207
+ video_bits_pixel_frame: 0.224,
208
+ video_stream_size: 8524920,
209
+ video_language: 'English',
210
+ video_color_primaries: 'BT.709-5, BT.1361, IEC 61966-2-4, SMPTE RP177',
211
+ video_transfer_characteristics: 'BT.709-5, BT.1361',
212
+ video_matrix_coefficients: 'BT.709-5, BT.1361, IEC 61966-2-4 709, SMPTE RP177',
213
+ audio_format: 'PCM',
214
+ audio_format_settings_endianness: 'Little',
215
+ audio_format_settings_sign: 'Signed',
216
+ audio_codec_id: 'sowt',
217
+ audio_duratio: 4903,
218
+ audio_bit_rate_mode: 'Constant',
219
+ audio_bit_rate: 1572864,
220
+ audio_channels: '2 channels',
221
+ audio_channel_positions: 'Front: L R',
222
+ audio_sampling_rate: '48.0 KHz',
223
+ audio_bit_depth: 16,
224
+ audio_stream_size: 941056,
225
+ audio_language: 'English',
226
+ image_format: 'PNG',
227
+ image_format_info: 'Portable Network Graphic',
228
+ image_file_size: 434176,
229
+ image_sub_format: 'LZ77',
230
+ image_width: 572,
231
+ image_height: 450,
232
+ image_resolution: 32
233
+ }
234
+ end
235
+
236
+ # mock video details player attributes response
237
+ def mock_video_player_attributes
238
+ {
239
+ template_name: 'default',
240
+ width: 640,
241
+ height: 360,
242
+ hold_frame: 'http://example.com/custom_hold_frame',
243
+ show_hold_frame: true,
244
+ sharing_enabled: true,
245
+ show_email_share: true,
246
+ show_embed_share: true,
247
+ show_social_share: true,
248
+ auto_play: false,
249
+ scaling: 'fit',
250
+ fade_in_speed: 0,
251
+ fade_out_speed: 0,
252
+ start_time: 0.000,
253
+ duration: 0.000,
254
+ show_controls: true,
255
+ auto_hide_controls: true,
256
+ auto_hide_controls_fullscreen_only: false,
257
+ auto_hide_controls_delay: 10000,
258
+ hardware_accelerated: false,
259
+ background_color: '#000000',
260
+ background_gradient: 'low',
261
+ time_color: '#01DAFF',
262
+ duration_color: '#FFFFFF',
263
+ progress_color: '#015B7A',
264
+ progress_gradient: 'medium',
265
+ buffer_color: '#6C9CBC',
266
+ buffer_gradient: 'none',
267
+ slider_color: '#000000',
268
+ slider_gradient: 'none',
269
+ button_color: '#889AA4',
270
+ button_over_color: '#92B2BD',
271
+ volume_slider_color: '#000000',
272
+ volume_color: '#000000',
273
+ volume_slider_gradient: 'none',
274
+ time_background_color: '#555555',
275
+ time_border_color: '#FFFFFF'
276
+ }
277
+ end