everybit 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +281 -0
- data/Rakefile +32 -0
- data/bin/everybit-console +7 -0
- data/everybit.gemspec +33 -0
- data/lib/everybit/account.rb +8 -0
- data/lib/everybit/collection.rb +17 -0
- data/lib/everybit/errors/authentication_error.rb +4 -0
- data/lib/everybit/errors/everybit_error.rb +20 -0
- data/lib/everybit/everybit_object.rb +32 -0
- data/lib/everybit/modules/createable.rb +13 -0
- data/lib/everybit/modules/deleteable.rb +14 -0
- data/lib/everybit/modules/listable.rb +15 -0
- data/lib/everybit/modules/updateable.rb +28 -0
- data/lib/everybit/resource.rb +21 -0
- data/lib/everybit/version.rb +3 -0
- data/lib/everybit/video.rb +33 -0
- data/lib/everybit.rb +78 -0
- data/spec/account_spec.rb +46 -0
- data/spec/misc_spec.rb +49 -0
- data/spec/spec_helper.rb +277 -0
- data/spec/video_spec.rb +318 -0
- metadata +139 -0
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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|