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/.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
|