vhx-ruby 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +2 -0
- data/Gemfile +2 -0
- data/README.md +59 -0
- data/Rakefile +1 -0
- data/lib/vhx.rb +66 -0
- data/lib/vhx/client.rb +86 -0
- data/lib/vhx/error.rb +24 -0
- data/lib/vhx/middleware/error_response.rb +32 -0
- data/lib/vhx/middleware/oauth2.rb +22 -0
- data/lib/vhx/oauth_token.rb +11 -0
- data/lib/vhx/objects/authorization.rb +5 -0
- data/lib/vhx/objects/collection.rb +8 -0
- data/lib/vhx/objects/collection_item.rb +4 -0
- data/lib/vhx/objects/customer.rb +8 -0
- data/lib/vhx/objects/product.rb +6 -0
- data/lib/vhx/objects/site.rb +4 -0
- data/lib/vhx/objects/user.rb +10 -0
- data/lib/vhx/objects/video.rb +7 -0
- data/lib/vhx/objects/video_file.rb +4 -0
- data/lib/vhx/utilities/api_operations/create.rb +22 -0
- data/lib/vhx/utilities/api_operations/delete.rb +16 -0
- data/lib/vhx/utilities/api_operations/list.rb +21 -0
- data/lib/vhx/utilities/api_operations/request.rb +17 -0
- data/lib/vhx/utilities/api_operations/update.rb +15 -0
- data/lib/vhx/utilities/vhx_helper.rb +20 -0
- data/lib/vhx/utilities/vhx_list_object.rb +44 -0
- data/lib/vhx/utilities/vhx_object.rb +106 -0
- data/lib/vhx/version.rb +3 -0
- data/spec/client_spec.rb +69 -0
- data/spec/fixtures/sample_array_list.json +15 -0
- data/spec/fixtures/sample_file_response.json +18 -0
- data/spec/fixtures/sample_hash_list.json +23 -0
- data/spec/fixtures/sample_package_response.json +185 -0
- data/spec/fixtures/sample_site_response.json +26 -0
- data/spec/fixtures/sample_user_response.json +21 -0
- data/spec/fixtures/sample_video_response.json +51 -0
- data/spec/middleware/error_response_spec.rb +11 -0
- data/spec/middleware/oauth2_spec.rb +14 -0
- data/spec/objects/file_spec.rb +29 -0
- data/spec/objects/package_spec.rb +74 -0
- data/spec/objects/site_spec.rb +44 -0
- data/spec/objects/user_spec.rb +51 -0
- data/spec/objects/video_spec.rb +36 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/test_data.rb +55 -0
- data/spec/utilities/vhx_collection_spec.rb +27 -0
- data/spec/utilities/vhx_helper_spec.rb +47 -0
- data/spec/utilities/vhx_object_spec.rb +53 -0
- data/spec/vcr/Vhx_Client/application_user/_refresh_access_token/access_token_changed.yml +57 -0
- data/spec/vcr/Vhx_Client/application_user/_refresh_access_token/oauth_token_refreshed.yml +57 -0
- data/spec/vcr/Vhx_File/associations/are_present.yml +409 -0
- data/spec/vcr/Vhx_Middleware_ErrorResponse/unauthorized_user_credentials.yml +122 -0
- data/spec/vcr/Vhx_Middleware_OAuth2/access_token_refresh.yml +797 -0
- data/spec/vcr/Vhx_Package/_add_video/with_hypermedia/returns_package_object.yml +51 -0
- data/spec/vcr/Vhx_Package/_add_video/with_id/returns_package_object.yml +51 -0
- data/spec/vcr/Vhx_Package/_create/returns_package_object.yml +140 -0
- data/spec/vcr/Vhx_Package/_find/with_hypermedia.yml +243 -0
- data/spec/vcr/Vhx_Package/_find/with_id.yml +243 -0
- data/spec/vcr/Vhx_Package/_remove_video/with_hypermedia/returns_success.yml +51 -0
- data/spec/vcr/Vhx_Package/_remove_video/with_id/returns_success.yml +51 -0
- data/spec/vcr/Vhx_Package/associations/are_present.yml +195 -0
- data/spec/vcr/Vhx_Site/_create/returns_site_object.yml +91 -0
- data/spec/vcr/Vhx_Site/_find/with_hypermedia.yml +195 -0
- data/spec/vcr/Vhx_Site/_find/with_id.yml +195 -0
- data/spec/vcr/Vhx_User/_find/with_hypermedia.yml +81 -0
- data/spec/vcr/Vhx_User/_find/with_id.yml +81 -0
- data/spec/vcr/Vhx_User/_me/returns_user_object.yml +720 -0
- data/spec/vcr/Vhx_User/_update/returns_user_object.yml +212 -0
- data/spec/vcr/Vhx_VhxObject/associations/cache/retreive_if_available.yml +195 -0
- data/spec/vcr/Vhx_VhxObject/associations/falls_back_to_links.yml +310 -0
- data/spec/vcr/Vhx_Video/_create/returns_video_object.yml +125 -0
- data/spec/vcr/Vhx_Video/associations/are_present.yml +294 -0
- data/vhx.gemspec +27 -0
- metadata +204 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../vhx_list_object'
|
2
|
+
|
3
|
+
module Vhx
|
4
|
+
module ApiOperations
|
5
|
+
module List
|
6
|
+
module ClassMethods
|
7
|
+
def all(payload = {})
|
8
|
+
response = Vhx.connection.get do |req|
|
9
|
+
req.url '/' + get_klass.downcase + 's'
|
10
|
+
req.body = payload
|
11
|
+
end
|
12
|
+
VhxListObject.new(response.body, get_klass.downcase + 's')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(klass)
|
17
|
+
klass.extend(ClassMethods)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Vhx
|
2
|
+
module ApiOperations
|
3
|
+
module Request
|
4
|
+
module ClassMethods
|
5
|
+
def find(identifier)
|
6
|
+
response = Vhx.connection.get(get_hypermedia(identifier))
|
7
|
+
self.new(response.body)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.included(klass)
|
12
|
+
klass.extend(Vhx::HelperMethods)
|
13
|
+
klass.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Vhx
|
2
|
+
module HelperMethods
|
3
|
+
def get_klass
|
4
|
+
if self.is_a?(Class)
|
5
|
+
self.to_s.split("::").last
|
6
|
+
else
|
7
|
+
self.class.to_s.split("::").last
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_hypermedia(identifier, klass = nil)
|
12
|
+
if identifier.class.to_s.match(/Integer|Fixnum/)
|
13
|
+
klass ||= get_klass
|
14
|
+
return Vhx.client.api_base_url + '/' + klass.downcase + 's' + '/' + identifier.to_s #This url is based purely on VHX's API convention (not nested).
|
15
|
+
end
|
16
|
+
|
17
|
+
identifier
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Vhx
|
2
|
+
class VhxListObject < Array
|
3
|
+
|
4
|
+
def initialize(obj, list_type)
|
5
|
+
@obj = obj
|
6
|
+
|
7
|
+
if @obj.is_a?(Array)
|
8
|
+
ar = @obj.map{|association_hash| Object.const_get("Vhx::#{vhx_object_type(list_type)}").new(association_hash)}
|
9
|
+
elsif @obj.is_a?(Hash)
|
10
|
+
@previous, @next = @obj['_links']['prev']['href'], @obj['_links']['next']['href']
|
11
|
+
@total = @obj['total']
|
12
|
+
ar = @obj['_embedded'][list_type].map{|association_hash| Object.const_get("Vhx::#{vhx_object_type(list_type)}").new(association_hash)}
|
13
|
+
end
|
14
|
+
|
15
|
+
super(ar)
|
16
|
+
end
|
17
|
+
|
18
|
+
def previous
|
19
|
+
@previous # TODO
|
20
|
+
end
|
21
|
+
|
22
|
+
def next
|
23
|
+
@next # TODO
|
24
|
+
end
|
25
|
+
|
26
|
+
def total
|
27
|
+
@total
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def vhx_object_type(list_type)
|
33
|
+
case list_type
|
34
|
+
when 'items'
|
35
|
+
'Collection::Item'
|
36
|
+
when 'files'
|
37
|
+
'Video::File'
|
38
|
+
else
|
39
|
+
list_type.gsub(/s\z/, '').capitalize
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Vhx
|
2
|
+
class VhxObject
|
3
|
+
include HelperMethods
|
4
|
+
ASSOCIATION_WHITELIST = ['products', 'sites', 'site', 'videos', 'video', 'subscription', 'files', 'items', 'customer']
|
5
|
+
|
6
|
+
def initialize(obj_hash)
|
7
|
+
@obj_hash = obj_hash
|
8
|
+
|
9
|
+
validate_class(obj_hash)
|
10
|
+
create_readers(obj_hash)
|
11
|
+
create_associations(obj_hash)
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_json
|
15
|
+
@obj_hash.to_json
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_hash
|
19
|
+
@obj_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
def href
|
23
|
+
@obj_hash['_links']['self']['href']
|
24
|
+
end
|
25
|
+
|
26
|
+
def links
|
27
|
+
data = {}
|
28
|
+
@obj_hash['_links'].each do |k, v|
|
29
|
+
data[k] = v['href']
|
30
|
+
end
|
31
|
+
return OpenStruct.new(data)
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
def validate_class(obj_hash)
|
36
|
+
return nil unless obj_hash['_links'].fetch('self', nil)
|
37
|
+
|
38
|
+
href = obj_hash['_links']['self']['href']
|
39
|
+
klass = self.class.to_s.split("::")
|
40
|
+
klass.shift #strip out Vhx
|
41
|
+
klass = klass.join("_").downcase
|
42
|
+
|
43
|
+
is_valid_match = case klass
|
44
|
+
when 'collection_item'
|
45
|
+
href.match('video|file|collection')
|
46
|
+
when 'video_file'
|
47
|
+
href.match('file')
|
48
|
+
else
|
49
|
+
href.match(klass)
|
50
|
+
end
|
51
|
+
|
52
|
+
unless is_valid_match
|
53
|
+
raise InvalidResourceError.new 'The resource returned from the API does not match the resource requested'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_readers(obj_hash)
|
58
|
+
obj_hash.keys.each do |key|
|
59
|
+
next if key.match(/embedded|links/)
|
60
|
+
self.class.send(:define_method, key) do
|
61
|
+
return obj_hash[key]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_associations(obj_hash)
|
67
|
+
associations = (obj_hash.fetch('_links', {}).keys | obj_hash.fetch('_embedded', {}).keys).select{|k| ASSOCIATION_WHITELIST.include?(k)}
|
68
|
+
associations.each do |association_method|
|
69
|
+
self.class.send(:define_method, association_method) do |payload = {}|
|
70
|
+
if payload.empty? && obj_hash['_embedded'] && obj_hash['_embedded'].fetch(association_method, []).length > 0
|
71
|
+
return fetch_embedded_association(obj_hash, association_method)
|
72
|
+
end
|
73
|
+
|
74
|
+
if obj_hash['_links'] && obj_hash['_links'].fetch(association_method, []).length > 0
|
75
|
+
return fetch_linked_association(obj_hash, association_method, payload)
|
76
|
+
end
|
77
|
+
|
78
|
+
raise InvalidResourceError.new 'Association does not exist'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def fetch_embedded_association(obj_hash, association_method)
|
84
|
+
association_obj = obj_hash['_embedded'][association_method]
|
85
|
+
build_association(association_obj, association_method)
|
86
|
+
end
|
87
|
+
|
88
|
+
def fetch_linked_association(obj_hash, association_method, payload = {})
|
89
|
+
response = Vhx.connection.get do |req|
|
90
|
+
req.url(obj_hash['_links'][association_method]['href'].gsub(Vhx.client.api_base_url, ""))
|
91
|
+
req.body = payload
|
92
|
+
end
|
93
|
+
|
94
|
+
build_association(response.body, association_method)
|
95
|
+
end
|
96
|
+
|
97
|
+
def build_association(association_obj, association_method)
|
98
|
+
# Support for legacy arrays, and new list objects starting with Video resource
|
99
|
+
if association_obj.is_a?(Array) || association_obj.has_key?('total')
|
100
|
+
return VhxListObject.new(association_obj, association_method)
|
101
|
+
end
|
102
|
+
|
103
|
+
Object.const_get("Vhx::#{association_method.gsub(/s\z/, '').capitalize}").new(association_obj)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
data/lib/vhx/version.rb
ADDED
data/spec/client_spec.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Vhx::Client, :vcr do
|
4
|
+
describe 'faraday configuration' do
|
5
|
+
subject(:vhx_client){ Vhx::Client.new(application_only_credentials)}
|
6
|
+
|
7
|
+
it 'uses custom error response middleware' do
|
8
|
+
expect(vhx_client.connection.builder.handlers).to include(Vhx::Middleware::ErrorResponse)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'uses api host' do
|
12
|
+
expect(vhx_client.connection.url_prefix.host).to eq 'api.crystal.dev'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'application_only' do
|
17
|
+
subject(:vhx_client){ Vhx::Client.new(application_only_credentials)}
|
18
|
+
|
19
|
+
describe 'connection' do
|
20
|
+
it 'initializes faraday connection' do
|
21
|
+
expect(vhx_client.connection).to be_an_instance_of(Faraday::Connection)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'authorization header presence' do
|
25
|
+
expect(vhx_client.connection.headers['Authorization']).to_not be_nil
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'basic auth presence' do
|
29
|
+
expect(vhx_client.connection.headers['Authorization']).to match /Basic/
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'application_user' do
|
35
|
+
subject(:vhx_client){ Vhx::Client.new(application_user_credentials)}
|
36
|
+
|
37
|
+
it 'oauth_token presence' do
|
38
|
+
expect(vhx_client.oauth_token).to be_an_instance_of(OAuthToken)
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'connection' do
|
42
|
+
it 'initializes faraday connection' do
|
43
|
+
expect(vhx_client.connection).to be_an_instance_of(Faraday::Connection)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'authorization header presence' do
|
47
|
+
expect(vhx_client.connection.headers['Authorization']).to_not be_nil
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'Bearer auth presence' do
|
51
|
+
expect(vhx_client.connection.headers['Authorization']).to match /Bearer/
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#refresh_access_token!' do
|
56
|
+
subject(:oauth_token){ vhx_client.oauth_token }
|
57
|
+
let!(:original_access_token){ oauth_token.access_token }
|
58
|
+
before { vhx_client.refresh_access_token! }
|
59
|
+
|
60
|
+
it 'oauth_token refreshed' do
|
61
|
+
expect(vhx_client.oauth_token.refreshed).to eq(true)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'access_token changed' do
|
65
|
+
expect(vhx_client.oauth_token.access_token).to_not eq(original_access_token)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
[{
|
2
|
+
"_links": {
|
3
|
+
"self": { "href": "https://api.vhx.tv/videos/1/files?quality=adaptive&format=m3u8" },
|
4
|
+
"video": { "href": "https://api.vhx.tv/videos/1" },
|
5
|
+
"site": { "href": "https://api.vhx.tv/sites/1" }
|
6
|
+
},
|
7
|
+
"quality": "adaptive",
|
8
|
+
"format": "m3u8",
|
9
|
+
"method": "hls",
|
10
|
+
"size": {
|
11
|
+
"bytes": 1073741824,
|
12
|
+
"formatted": "1 GB"
|
13
|
+
},
|
14
|
+
"mime_type": "application/x-mpegURL"
|
15
|
+
}]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{
|
2
|
+
"_links": {
|
3
|
+
"self": { "href": "http://api.crystal.dev/videos/3008/files?quality=adaptive&format=m3u8" },
|
4
|
+
"video": { "href": "http://api.crystal.dev/videos/3008" },
|
5
|
+
"site": { "href": "http://api.crystal.dev/sites/1900" },
|
6
|
+
"source": { "href": "http://video.crystal.dev/mymovie/adaptive.m3u8?token=f4v3v3i4c2o209_3" }
|
7
|
+
},
|
8
|
+
"quality": "adaptive",
|
9
|
+
"format": "m3u8",
|
10
|
+
"method": "hls",
|
11
|
+
"size": {
|
12
|
+
"bytes": 1073741824,
|
13
|
+
"formatted": "1 GB"
|
14
|
+
},
|
15
|
+
"mime_type": "application/x-mpegURL",
|
16
|
+
"created_at": "2014-02-25T20:19:30Z",
|
17
|
+
"updated_at": "2014-02-25T20:19:30Z"
|
18
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
{
|
2
|
+
"_links": {
|
3
|
+
"prev": {"href": "pending"},
|
4
|
+
"next": {"href": "pending"}
|
5
|
+
},
|
6
|
+
"_embedded": {
|
7
|
+
"files": [{
|
8
|
+
"_links": {
|
9
|
+
"self": { "href": "https://api.vhx.tv/videos/1/files?quality=adaptive&format=m3u8" },
|
10
|
+
"video": { "href": "https://api.vhx.tv/videos/1" },
|
11
|
+
"site": { "href": "https://api.vhx.tv/sites/1" }
|
12
|
+
},
|
13
|
+
"quality": "adaptive",
|
14
|
+
"format": "m3u8",
|
15
|
+
"method": "hls",
|
16
|
+
"size": {
|
17
|
+
"bytes": 1073741824,
|
18
|
+
"formatted": "1 GB"
|
19
|
+
},
|
20
|
+
"mime_type": "application/x-mpegURL"
|
21
|
+
}]
|
22
|
+
}
|
23
|
+
}
|
@@ -0,0 +1,185 @@
|
|
1
|
+
{
|
2
|
+
"_links": {
|
3
|
+
"self": {
|
4
|
+
"href": "http://api.crystal.dev/packages/1025"
|
5
|
+
},
|
6
|
+
"site": {
|
7
|
+
"href": "http://api.crystal.dev/sites/1900"
|
8
|
+
},
|
9
|
+
"videos": {
|
10
|
+
"href": "http://api.crystal.dev/packages/1025/videos"
|
11
|
+
},
|
12
|
+
"buy_page": {
|
13
|
+
"href": "http://sagartestmovie.crystal.dev/buy/testing123"
|
14
|
+
},
|
15
|
+
"home_page": {
|
16
|
+
"href": "http://sagartestmovie.crystal.dev/packages/testing123"
|
17
|
+
}
|
18
|
+
},
|
19
|
+
"_embedded": {
|
20
|
+
"site": {
|
21
|
+
"_links": {
|
22
|
+
"self": {
|
23
|
+
"href": "http://api.crystal.dev/sites/1900"
|
24
|
+
},
|
25
|
+
"home_page": {
|
26
|
+
"href": "http://sagartestmovie.crystal.dev"
|
27
|
+
},
|
28
|
+
"followers": {
|
29
|
+
"href": "http://api.crystal.dev/sites/1900/followers"
|
30
|
+
}
|
31
|
+
},
|
32
|
+
"id": 1900,
|
33
|
+
"title": "SagarTestMovie",
|
34
|
+
"description": "This is my test movie. ",
|
35
|
+
"domain": "sagartestmovie.crystal.dev",
|
36
|
+
"subdomain": "sagartestmovie",
|
37
|
+
"key": "sagartestmovie",
|
38
|
+
"color": "#28DBF7",
|
39
|
+
"facebook_url": null,
|
40
|
+
"twitter_name": null,
|
41
|
+
"google_analytics_id": "",
|
42
|
+
"packages_count": 2,
|
43
|
+
"videos_count": 4,
|
44
|
+
"followers_count": 31,
|
45
|
+
"created_at": "2013-12-27T00:20:28Z",
|
46
|
+
"updated_at": "2015-05-04T20:46:01Z"
|
47
|
+
},
|
48
|
+
"videos": [
|
49
|
+
{
|
50
|
+
"_links": {
|
51
|
+
"self": {
|
52
|
+
"href": "http://api.crystal.dev/videos/3008"
|
53
|
+
},
|
54
|
+
"site": {
|
55
|
+
"href": "http://api.crystal.dev/sites/1900"
|
56
|
+
},
|
57
|
+
"files": {
|
58
|
+
"href": "http://api.crystal.dev/videos/3008/files"
|
59
|
+
}
|
60
|
+
},
|
61
|
+
"_embedded": {
|
62
|
+
"subtitles": [
|
63
|
+
{
|
64
|
+
"_links": {
|
65
|
+
"self": {
|
66
|
+
"href": "http://api.crystal.dev/videos/7726"
|
67
|
+
},
|
68
|
+
"video": {
|
69
|
+
"href": "http://api.crystal.dev/videos/3008"
|
70
|
+
},
|
71
|
+
"site": {
|
72
|
+
"href": "http://api.crystal.dev/sites/1900"
|
73
|
+
}
|
74
|
+
},
|
75
|
+
"language": "Bengali",
|
76
|
+
"type": "video"
|
77
|
+
},
|
78
|
+
{
|
79
|
+
"_links": {
|
80
|
+
"self": {
|
81
|
+
"href": "http://api.crystal.dev/videos/5558"
|
82
|
+
},
|
83
|
+
"video": {
|
84
|
+
"href": "http://api.crystal.dev/videos/3008"
|
85
|
+
},
|
86
|
+
"site": {
|
87
|
+
"href": "http://api.crystal.dev/sites/1900"
|
88
|
+
}
|
89
|
+
},
|
90
|
+
"language": "English",
|
91
|
+
"type": "video"
|
92
|
+
}
|
93
|
+
]
|
94
|
+
},
|
95
|
+
"id": 3008,
|
96
|
+
"title": "Test Movie",
|
97
|
+
"description": "Testing",
|
98
|
+
"status": "uploaded",
|
99
|
+
"duration": {
|
100
|
+
"seconds": 19,
|
101
|
+
"formatted": "00:00:19"
|
102
|
+
},
|
103
|
+
"thumbnail": {
|
104
|
+
"small": "https://dv6n47kh00ig2.cloudfront.net/sagartestmovie/assets/images/video-3008-1403716255-240x135.jpg",
|
105
|
+
"medium": "https://dv6n47kh00ig2.cloudfront.net/sagartestmovie/assets/images/video-3008-1403716255-640x360.jpg",
|
106
|
+
"large": "https://dv6n47kh00ig2.cloudfront.net/sagartestmovie/assets/images/video-3008-1403716255-1280x720.jpg"
|
107
|
+
},
|
108
|
+
"is_drm_enabled": false,
|
109
|
+
"subtitles_count": 2,
|
110
|
+
"files_count": 5,
|
111
|
+
"created_at": "2014-02-06T05:30:18Z",
|
112
|
+
"updated_at": "2015-02-18T16:21:24Z",
|
113
|
+
"position": 0
|
114
|
+
},
|
115
|
+
{
|
116
|
+
"_links": {
|
117
|
+
"self": {
|
118
|
+
"href": "http://api.crystal.dev/videos/7830"
|
119
|
+
},
|
120
|
+
"site": {
|
121
|
+
"href": "http://api.crystal.dev/sites/1900"
|
122
|
+
},
|
123
|
+
"files": {
|
124
|
+
"href": "http://api.crystal.dev/videos/7830/files"
|
125
|
+
}
|
126
|
+
},
|
127
|
+
"_embedded": {
|
128
|
+
"subtitles": [
|
129
|
+
|
130
|
+
]
|
131
|
+
},
|
132
|
+
"id": 7830,
|
133
|
+
"title": "test movie",
|
134
|
+
"description": null,
|
135
|
+
"status": null,
|
136
|
+
"duration": {
|
137
|
+
"seconds": 0,
|
138
|
+
"formatted": "00:00:00"
|
139
|
+
},
|
140
|
+
"thumbnail": {
|
141
|
+
"small": "http://cdn.crystal.dev/assets/thumbnails/default-small.png",
|
142
|
+
"medium": "http://cdn.crystal.dev/assets/thumbnails/default-medium.png",
|
143
|
+
"large": "http://cdn.crystal.dev/assets/thumbnails/default-large.png"
|
144
|
+
},
|
145
|
+
"is_drm_enabled": false,
|
146
|
+
"subtitles_count": 0,
|
147
|
+
"files_count": 0,
|
148
|
+
"created_at": "2014-07-14T15:19:03Z",
|
149
|
+
"updated_at": "2015-05-04T19:36:50Z",
|
150
|
+
"position": 1
|
151
|
+
}
|
152
|
+
],
|
153
|
+
"trailer": null
|
154
|
+
},
|
155
|
+
"id": 1025,
|
156
|
+
"title": "testing123",
|
157
|
+
"description": "test",
|
158
|
+
"sku": "testing123",
|
159
|
+
"price": {
|
160
|
+
"cents": 200,
|
161
|
+
"currency": "USD",
|
162
|
+
"formatted": "$2",
|
163
|
+
"US": {
|
164
|
+
"cents": 200,
|
165
|
+
"currency": "USD",
|
166
|
+
"formatted": "$2"
|
167
|
+
}
|
168
|
+
},
|
169
|
+
"rental": null,
|
170
|
+
"trailer_url": null,
|
171
|
+
"trailer_embed_code": "<iframe src=\"http://embed.crystal.dev/packages/1025\" width=\"640\" height=\"360\" frameborder=\"0\" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>",
|
172
|
+
"thumbnail": {
|
173
|
+
"small": "http://cdn.crystal.dev/assets/thumbnails/default-small.png",
|
174
|
+
"medium": "http://cdn.crystal.dev/assets/thumbnails/default-medium.png",
|
175
|
+
"large": "http://cdn.crystal.dev/assets/thumbnails/default-large.png",
|
176
|
+
"blurred": null
|
177
|
+
},
|
178
|
+
"is_active": false,
|
179
|
+
"is_preorder": false,
|
180
|
+
"release_date": null,
|
181
|
+
"videos_count": 2,
|
182
|
+
"extras_count": 0,
|
183
|
+
"created_at": "2014-02-06T18:00:39Z",
|
184
|
+
"updated_at": "2015-02-18T16:21:15Z"
|
185
|
+
}
|