vzaar_api 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +4 -0
  4. data/.tool-versions +1 -0
  5. data/.travis.yml +3 -0
  6. data/Changelog +50 -0
  7. data/Gemfile +3 -0
  8. data/Guardfile +25 -0
  9. data/README.md +55 -0
  10. data/Rakefile +26 -0
  11. data/examples/README.md +33 -0
  12. data/examples/api_envs.yml.example +31 -0
  13. data/examples/category/create_update_delete_spec.rb +100 -0
  14. data/examples/category/list_spec.rb +38 -0
  15. data/examples/category/list_subtree_spec.rb +40 -0
  16. data/examples/category/lookup_spec.rb +35 -0
  17. data/examples/encoding_preset/list_spec.rb +38 -0
  18. data/examples/encoding_preset/lookup_spec.rb +35 -0
  19. data/examples/ingest_recipe/create_update_delete_spec.rb +70 -0
  20. data/examples/ingest_recipe/list_spec.rb +38 -0
  21. data/examples/ingest_recipe/lookup_spec.rb +35 -0
  22. data/examples/playlist/create_update_delete_spec.rb +97 -0
  23. data/examples/playlist/list_spec.rb +37 -0
  24. data/examples/playlist/lookup_spec.rb +34 -0
  25. data/examples/rate_limit_spec.rb +18 -0
  26. data/examples/spec_helper.rb +17 -0
  27. data/examples/support/helpers.rb +16 -0
  28. data/examples/support/videos/medium.mp4 +0 -0
  29. data/examples/support/videos/small.mp4 +0 -0
  30. data/examples/video/create_update_delete_spec.rb +73 -0
  31. data/lib/vzaar_api/abstract.rb +9 -0
  32. data/lib/vzaar_api/category.rb +39 -0
  33. data/lib/vzaar_api/encoding_preset.rb +19 -0
  34. data/lib/vzaar_api/ingest_recipe.rb +35 -0
  35. data/lib/vzaar_api/legacy_rendition.rb +11 -0
  36. data/lib/vzaar_api/lib/active_object.rb +92 -0
  37. data/lib/vzaar_api/lib/api.rb +54 -0
  38. data/lib/vzaar_api/lib/api_response.rb +61 -0
  39. data/lib/vzaar_api/lib/has_attributes.rb +49 -0
  40. data/lib/vzaar_api/lib/has_collection_builder.rb +17 -0
  41. data/lib/vzaar_api/lib/has_resource_url.rb +24 -0
  42. data/lib/vzaar_api/lib/paged_resource.rb +80 -0
  43. data/lib/vzaar_api/lib/will_paginate.rb +22 -0
  44. data/lib/vzaar_api/link_upload.rb +14 -0
  45. data/lib/vzaar_api/playlist.rb +29 -0
  46. data/lib/vzaar_api/rendition.rb +16 -0
  47. data/lib/vzaar_api/signature/abstract.rb +40 -0
  48. data/lib/vzaar_api/signature/factory.rb +39 -0
  49. data/lib/vzaar_api/signature/multipart.rb +23 -0
  50. data/lib/vzaar_api/signature/single.rb +17 -0
  51. data/lib/vzaar_api/strategy/video/create.rb +46 -0
  52. data/lib/vzaar_api/upload/s3.rb +90 -0
  53. data/lib/vzaar_api/upload/virtual_file.rb +14 -0
  54. data/lib/vzaar_api/version.rb +4 -0
  55. data/lib/vzaar_api/video.rb +38 -0
  56. data/lib/vzaar_api.rb +60 -0
  57. data/spec/fixtures/vcr_cassettes/categories/each_item.yml +363 -0
  58. data/spec/fixtures/vcr_cassettes/categories/find.yml +61 -0
  59. data/spec/fixtures/vcr_cassettes/categories/find_404.yml +49 -0
  60. data/spec/fixtures/vcr_cassettes/categories/paginate_first.yml +61 -0
  61. data/spec/fixtures/vcr_cassettes/categories/paginate_last.yml +119 -0
  62. data/spec/fixtures/vcr_cassettes/categories/paginate_next.yml +120 -0
  63. data/spec/fixtures/vcr_cassettes/categories/paginate_previous.yml +120 -0
  64. data/spec/fixtures/vcr_cassettes/categories/subtree.yml +127 -0
  65. data/spec/fixtures/vcr_cassettes/categories/subtree_paginate_first.yml +123 -0
  66. data/spec/fixtures/vcr_cassettes/categories/subtree_paginate_last.yml +185 -0
  67. data/spec/fixtures/vcr_cassettes/categories/subtree_paginate_next.yml +184 -0
  68. data/spec/fixtures/vcr_cassettes/categories/subtree_paginate_previous.yml +184 -0
  69. data/spec/fixtures/vcr_cassettes/encoding_presets/each_item.yml +299 -0
  70. data/spec/fixtures/vcr_cassettes/encoding_presets/find.yml +62 -0
  71. data/spec/fixtures/vcr_cassettes/encoding_presets/find_404.yml +51 -0
  72. data/spec/fixtures/vcr_cassettes/encoding_presets/paginate_first.yml +62 -0
  73. data/spec/fixtures/vcr_cassettes/encoding_presets/paginate_last.yml +121 -0
  74. data/spec/fixtures/vcr_cassettes/encoding_presets/paginate_next.yml +121 -0
  75. data/spec/fixtures/vcr_cassettes/encoding_presets/paginate_previous.yml +121 -0
  76. data/spec/fixtures/vcr_cassettes/ingest_recipes/create_200.yml +63 -0
  77. data/spec/fixtures/vcr_cassettes/ingest_recipes/create_422.yml +52 -0
  78. data/spec/fixtures/vcr_cassettes/ingest_recipes/delete_204.yml +166 -0
  79. data/spec/fixtures/vcr_cassettes/ingest_recipes/delete_422.yml +112 -0
  80. data/spec/fixtures/vcr_cassettes/ingest_recipes/each_item.yml +182 -0
  81. data/spec/fixtures/vcr_cassettes/ingest_recipes/find.yml +62 -0
  82. data/spec/fixtures/vcr_cassettes/ingest_recipes/find_404.yml +51 -0
  83. data/spec/fixtures/vcr_cassettes/ingest_recipes/paginate_first.yml +62 -0
  84. data/spec/fixtures/vcr_cassettes/ingest_recipes/paginate_last.yml +122 -0
  85. data/spec/fixtures/vcr_cassettes/ingest_recipes/paginate_next.yml +121 -0
  86. data/spec/fixtures/vcr_cassettes/ingest_recipes/paginate_previous.yml +122 -0
  87. data/spec/fixtures/vcr_cassettes/ingest_recipes/update_200.yml +242 -0
  88. data/spec/fixtures/vcr_cassettes/ingest_recipes/update_422.yml +113 -0
  89. data/spec/fixtures/vcr_cassettes/playlists/each_item.yml +607 -0
  90. data/spec/fixtures/vcr_cassettes/playlists/find.yml +66 -0
  91. data/spec/fixtures/vcr_cassettes/playlists/find_404.yml +51 -0
  92. data/spec/fixtures/vcr_cassettes/playlists/paginate_first.yml +74 -0
  93. data/spec/fixtures/vcr_cassettes/playlists/paginate_last.yml +146 -0
  94. data/spec/fixtures/vcr_cassettes/playlists/paginate_next.yml +145 -0
  95. data/spec/fixtures/vcr_cassettes/playlists/paginate_previous.yml +145 -0
  96. data/spec/fixtures/vcr_cassettes/signature/multipart_201.yml +62 -0
  97. data/spec/fixtures/vcr_cassettes/signature/multipart_422.yml +52 -0
  98. data/spec/fixtures/vcr_cassettes/signature/single_201.yml +62 -0
  99. data/spec/fixtures/vcr_cassettes/signature/single_422.yml +51 -0
  100. data/spec/fixtures/vcr_cassettes/upload/multipart_201.yml +279868 -0
  101. data/spec/fixtures/vcr_cassettes/upload/multipart_403.yml +116578 -0
  102. data/spec/fixtures/vcr_cassettes/upload/single_201.yml +23388 -0
  103. data/spec/fixtures/vcr_cassettes/upload/single_403.yml +23374 -0
  104. data/spec/fixtures/vcr_cassettes/videos/create/error.yml +51 -0
  105. data/spec/fixtures/vcr_cassettes/videos/create/guid_201.yml +65 -0
  106. data/spec/fixtures/vcr_cassettes/videos/create/guid_error.yml +52 -0
  107. data/spec/fixtures/vcr_cassettes/videos/create/link_201.yml +65 -0
  108. data/spec/fixtures/vcr_cassettes/videos/create/link_error.yml +51 -0
  109. data/spec/fixtures/vcr_cassettes/videos/create/path_201.yml +23509 -0
  110. data/spec/fixtures/vcr_cassettes/videos/delete_204.yml +168 -0
  111. data/spec/fixtures/vcr_cassettes/videos/find.yml +66 -0
  112. data/spec/fixtures/vcr_cassettes/videos/find_404.yml +51 -0
  113. data/spec/fixtures/vcr_cassettes/videos/paginate_first.yml +71 -0
  114. data/spec/fixtures/vcr_cassettes/videos/paginate_last.yml +137 -0
  115. data/spec/fixtures/vcr_cassettes/videos/paginate_next.yml +139 -0
  116. data/spec/fixtures/vcr_cassettes/videos/paginate_previous.yml +139 -0
  117. data/spec/spec_helper.rb +103 -0
  118. data/spec/support/files/video-1.0MB.mp4 +0 -0
  119. data/spec/support/files/video-12.0MB.mp4 +0 -0
  120. data/spec/support/files/video-4.9MB.mp4 +0 -0
  121. data/spec/support/files/video-5.0MB.mp4 +0 -0
  122. data/spec/support/helpers.rb +16 -0
  123. data/spec/vzaar_api/category_spec.rb +141 -0
  124. data/spec/vzaar_api/encoding_preset_spec.rb +92 -0
  125. data/spec/vzaar_api/ingest_recipe_spec.rb +197 -0
  126. data/spec/vzaar_api/lib/api_spec.rb +28 -0
  127. data/spec/vzaar_api/playlist_spec.rb +97 -0
  128. data/spec/vzaar_api/rendition_spec.rb +55 -0
  129. data/spec/vzaar_api/signature/factory_spec.rb +68 -0
  130. data/spec/vzaar_api/signature/multipart_spec.rb +81 -0
  131. data/spec/vzaar_api/signature/single_spec.rb +72 -0
  132. data/spec/vzaar_api/upload/s3_spec.rb +112 -0
  133. data/spec/vzaar_api/video_spec.rb +248 -0
  134. data/spec/vzaar_api/vzaar_api_spec.rb +18 -0
  135. data/spec/vzaar_api_helper.rb +19 -0
  136. data/vzaar.png +0 -0
  137. data/vzaar_api.gemspec +35 -0
  138. metadata +413 -0
@@ -0,0 +1,49 @@
1
+ module VzaarApi
2
+ module Lib
3
+ module HasAttributes
4
+
5
+ def self.prepended(klass)
6
+ klass::ATTR_READERS.each do |attr|
7
+ klass.send :attr_reader, attr
8
+ end
9
+
10
+ unless defined? klass::ATTR_ACCESSORS
11
+ klass.const_set 'ATTR_ACCESSORS', [].freeze
12
+ end
13
+
14
+ klass::ATTR_ACCESSORS.each do |attr|
15
+ klass.send :attr_accessor, attr
16
+
17
+ klass.send(:define_method, "#{attr}=") do |val|
18
+ if self.changes[attr]
19
+ self.changes[attr][1] = val
20
+ else
21
+ self.changes[attr] = [self.send(attr), val]
22
+ end
23
+ val
24
+ end
25
+ end
26
+ end
27
+
28
+ def initialize(attrs = {})
29
+ self.class::ATTR_READERS.each do |attr|
30
+ instance_variable_set("@#{attr}", attrs[attr])
31
+ end
32
+ self.class::ATTR_ACCESSORS.each do |attr|
33
+ instance_variable_set("@#{attr}", attrs[attr])
34
+ end
35
+ super
36
+ end
37
+
38
+ private
39
+
40
+ def update_from_attributes(attrs = {})
41
+ attrs.each do |attr, val|
42
+ instance_variable_set("@#{attr}", attrs[attr])
43
+ end
44
+ super
45
+ end
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,17 @@
1
+ module VzaarApi
2
+ module Lib
3
+ module HasCollectionBuilder
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def build(data = [])
11
+ Array(data).map { |attrs| new attrs }
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ module VzaarApi
2
+ module Lib
3
+ module HasResourceUrl
4
+
5
+ def self.included(base)
6
+ base.include(InstanceMethods)
7
+ base.extend(ClassMethods)
8
+ end
9
+
10
+ module InstanceMethods
11
+ def resource_url(path = nil)
12
+ self.class.resource_url(path)
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def resource_url(path = nil)
18
+ Api.resource_url self::ENDPOINT, path
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,80 @@
1
+ module VzaarApi
2
+ module Lib
3
+ class PagedResource
4
+
5
+ attr_reader :query, :meta, :collection, :resource_class, :resource_url
6
+
7
+ def initialize(query = {})
8
+ @query = query.dup
9
+ @resource_class = @query.delete(:resource_class)
10
+ @resource_url = @query.delete(:resource_url)
11
+ @loaded = false
12
+ end
13
+
14
+ def loaded?
15
+ @loaded
16
+ end
17
+
18
+ def each_item
19
+ return enum_for :each_item unless block_given?
20
+ begin
21
+ each { |record| yield record }
22
+ end while !self.next.empty?
23
+ end
24
+
25
+ def first
26
+ loaded? ? load_page_url(:first) : load!
27
+ end
28
+
29
+ def next
30
+ load_page_url :next
31
+ end
32
+
33
+ def previous
34
+ load_page_url :previous
35
+ end
36
+
37
+ def last
38
+ load_page_url :last
39
+ end
40
+
41
+ private
42
+
43
+ def load!
44
+ @loaded = true
45
+ load_from_url resource_url, query
46
+ end
47
+
48
+ def load_page_url(page)
49
+ load! unless loaded?
50
+ if url = meta_link(page)
51
+ load_from_url meta[:links][page]
52
+ else
53
+ []
54
+ end
55
+ end
56
+
57
+ def meta_link(page)
58
+ return unless meta
59
+ meta[:links][page]
60
+ end
61
+
62
+ def each
63
+ return enum_for :each unless block_given?
64
+ load! unless collection
65
+ collection.each { |record| yield record }
66
+ end
67
+
68
+ def load_from_url(url, query = {})
69
+ response = Api.new.get(url, query)
70
+ @meta = response.meta
71
+ @collection = build_collection response.data
72
+ end
73
+
74
+ def build_collection(items)
75
+ items.map { |attrs| resource_class.new attrs }
76
+ end
77
+
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,22 @@
1
+ module VzaarApi
2
+ module Lib
3
+ module WillPaginate
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def each_item(query = {}, &block)
11
+ paginate(query).each_item(&block)
12
+ end
13
+
14
+ def paginate(query = {})
15
+ args = query.merge({ resource_url: resource_url, resource_class: self })
16
+ Lib::PagedResource.new(args)
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module VzaarApi
2
+ module LinkUpload
3
+
4
+ include Lib::HasResourceUrl
5
+
6
+ ENDPOINT = 'link_uploads'
7
+
8
+ def self.create(attrs = {})
9
+ attrs[:uploader] = UPLOADER
10
+ Video.new Lib::Api.new.post(resource_url, attrs).data
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module VzaarApi
2
+ class Playlist < Abstract
3
+
4
+ ENDPOINT = 'feeds/playlists'
5
+
6
+ ATTR_READERS = %i(
7
+ id title sort_order sort_by autoplay continuous_play category_id
8
+ embed_code created_at updated_at
9
+ ).freeze
10
+
11
+ ATTR_ACCESSORS = %i(
12
+ category_id title sort_by sort_order private dimensions max_vids
13
+ position autoplay continuous_play max_vids
14
+ ).freeze
15
+
16
+ prepend Lib::HasAttributes
17
+ include Lib::HasCollectionBuilder
18
+ include Lib::HasResourceUrl
19
+ include Lib::ActiveObject::Find
20
+ include Lib::ActiveObject::Save
21
+ include Lib::ActiveObject::Delete
22
+ include Lib::WillPaginate
23
+
24
+ def self.create(attrs = {})
25
+ url = Lib::Api.resource_url(ENDPOINT)
26
+ new Lib::Api.new.post(url, attrs).data
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ module VzaarApi
2
+ class Rendition < Abstract
3
+
4
+ ATTR_READERS = [:audio_bitrate_kbps, :audio_channels,
5
+ :audio_sample_rate, :bitrate_kbps,
6
+ :encoding_preset_id, :error_message,
7
+ :frame_rate, :height, :id, :keyframe,
8
+ :name, :output_format, :profile, :size_in_bytes,
9
+ :source_as_rendition, :state, :video_codec, :width,
10
+ :created_at, :updated_at].freeze
11
+
12
+ prepend Lib::HasAttributes
13
+ include Lib::HasCollectionBuilder
14
+
15
+ end
16
+ end
@@ -0,0 +1,40 @@
1
+ module VzaarApi
2
+ module Signature
3
+ class Abstract
4
+
5
+ include Lib::HasResourceUrl
6
+
7
+ attr_reader :access_key_id, :acl, :bucket, :content_type,
8
+ :guid, :key, :policy, :signature, :success_action_status,
9
+ :upload_hostname
10
+
11
+ def initialize(attrs = {})
12
+ @access_key_id = attrs[:access_key_id]
13
+ @acl = attrs[:acl]
14
+ @bucket = attrs[:bucket]
15
+ @content_type = attrs[:content_type]
16
+ @guid = attrs[:guid]
17
+ @key = attrs[:key]
18
+ @policy = attrs[:policy]
19
+ @signature = attrs[:signature]
20
+ @success_action_status = attrs[:success_action_status]
21
+ @upload_hostname = attrs[:upload_hostname]
22
+ after_initialize(attrs)
23
+ end
24
+
25
+ def after_initialize(attrs = {})
26
+ raise Error.new('Cannot call #after_initialize on Signature::Abstract')
27
+ end
28
+
29
+ def multipart?
30
+ raise Error.new('Cannot call #multipart? on Signature::Abstract')
31
+ end
32
+
33
+ def self.create(attrs = {})
34
+ attrs[:uploader] = UPLOADER
35
+ new Lib::Api.new.post(resource_url, attrs).data
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,39 @@
1
+ module VzaarApi
2
+ module Signature
3
+ class Factory
4
+
5
+ # 5MB is min size required for multipart upload
6
+ MIN_S3_MULTIPART_FILE_SIZE = 5 * (1024 ** 2)
7
+
8
+ attr_reader :attrs, :path
9
+
10
+ def initialize(attrs)
11
+ @attrs = attrs
12
+ @path = attrs.fetch(:path)
13
+ end
14
+
15
+ def self.create(attrs)
16
+ new(attrs).create
17
+ end
18
+
19
+ def create
20
+ klass = multipart? ? Multipart : Single
21
+ klass.create(multipart_attrs)
22
+ end
23
+
24
+ def multipart?
25
+ multipart_attrs[:filesize].to_i >= MIN_S3_MULTIPART_FILE_SIZE
26
+ end
27
+
28
+ def multipart_attrs
29
+ {
30
+ filesize: File::Stat.new(path).size,
31
+ filename: File.basename(path)
32
+ }
33
+ rescue Errno::ENOENT
34
+ raise Error.new 'Invalid parameters: path is invalid'
35
+ end
36
+
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ module VzaarApi
2
+ module Signature
3
+ class Multipart < Abstract
4
+
5
+ include Lib::HasResourceUrl
6
+
7
+ ENDPOINT = 'signature/multipart'
8
+
9
+ attr_reader :upload_hostname, :part_size, :part_size_in_bytes, :parts
10
+
11
+ def after_initialize(attrs = {})
12
+ @part_size = attrs[:part_size]
13
+ @part_size_in_bytes = attrs[:part_size_in_bytes]
14
+ @parts = attrs[:parts]
15
+ end
16
+
17
+ def multipart?
18
+ true
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,17 @@
1
+ module VzaarApi
2
+ module Signature
3
+ class Single < Abstract
4
+
5
+ ENDPOINT = 'signature/single'
6
+
7
+ def after_initialize(attrs = {})
8
+ # no-op in this class
9
+ end
10
+
11
+ def multipart?
12
+ false
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ module VzaarApi
2
+ module Strategy
3
+ module Video
4
+ class Create
5
+
6
+ attr_reader :attrs, :video_class
7
+
8
+ def initialize(attrs, video_class)
9
+ @attrs = attrs
10
+ @video_class = video_class
11
+ end
12
+
13
+ def execute
14
+ case
15
+ when attrs.has_key?(:guid)
16
+ create_from_guid
17
+ when attrs.has_key?(:path)
18
+ create_from_path
19
+ when attrs.has_key?(:url)
20
+ create_from_url
21
+ else
22
+ raise Error.new('Invalid parameters: Expected one of :guid, :path, :url')
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def create_from_guid
29
+ url = Lib::Api.resource_url video_class::ENDPOINT
30
+ video_class.new Lib::Api.new.post(url, attrs).data
31
+ end
32
+
33
+ def create_from_path
34
+ signature = Signature::Factory.create(attrs)
35
+ upload_attrs = Upload::S3.new(attrs, signature).execute
36
+ video_class.create upload_attrs
37
+ end
38
+
39
+ def create_from_url
40
+ LinkUpload.create(attrs.merge({ uploader: UPLOADER }))
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,90 @@
1
+ module VzaarApi
2
+ module Upload
3
+ class S3
4
+ extend Forwardable
5
+
6
+ SEND_TIMEOUT = 1800
7
+
8
+ attr_reader :attrs, :path, :signature
9
+
10
+ def_delegators :@signature, :access_key_id, :acl, :bucket,
11
+ :guid, :key, :multipart?, :part_size_in_bytes, :policy,
12
+ :success_action_status, :upload_hostname
13
+
14
+ def initialize(attrs, signature)
15
+ @attrs = attrs.dup
16
+ @path = @attrs.delete(:path)
17
+ @signature = signature
18
+ end
19
+
20
+ def execute
21
+ if multipart?
22
+ multipart_upload
23
+ else
24
+ single_part_upload
25
+ end
26
+ attrs.merge({ guid: guid })
27
+ end
28
+
29
+ private
30
+
31
+ def multipart_upload
32
+ _headers = headers.dup
33
+ chunk = 0
34
+ File.open(path, "r") do |file|
35
+ until file.eof?
36
+ _headers['key'] = "#{key}.#{chunk}"
37
+ _headers['file'] = VirtualFile.new(file, part_size_in_bytes)
38
+ validate_response! upload_file(_headers)
39
+ chunk += 1
40
+ end
41
+ end
42
+ rescue => e
43
+ raise Error.new(e.message)
44
+ end
45
+
46
+ def single_part_upload
47
+ File.open(path, "r") do |file|
48
+ _headers = headers.dup
49
+ _headers['key'] = key
50
+ _headers['file'] = file
51
+ validate_response! upload_file(_headers)
52
+ end
53
+ rescue => e
54
+ raise Error.new(e.message)
55
+ end
56
+
57
+ def upload_file(headers)
58
+ http_client.post upload_hostname, headers
59
+ end
60
+
61
+ def headers
62
+ @headers ||= {
63
+ 'acl' => acl,
64
+ 'bucket' => bucket,
65
+ 'success_action_status' => success_action_status,
66
+ 'policy' => policy,
67
+ 'AWSAccessKeyId' => access_key_id,
68
+ 'signature' => signature.signature,
69
+ 'x-amz-meta-uploader' => UPLOADER
70
+ }
71
+ end
72
+
73
+ def http_client
74
+ @http_client ||= begin
75
+ HTTPClient.new.tap { |c| c.send_timeout = SEND_TIMEOUT }
76
+ end
77
+ end
78
+
79
+ def validate_response!(response)
80
+ return if response.ok?
81
+ raise error_message(response.body)
82
+ end
83
+
84
+ def error_message(body)
85
+ /Message\>(.+)\<\/Message/.match(body)[1]
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,14 @@
1
+ module VzaarApi
2
+ module Upload
3
+ class VirtualFile < StringIO
4
+
5
+ attr_reader :path
6
+
7
+ def initialize(file, chunk_size)
8
+ @path = File.basename file.path
9
+ super file.read(chunk_size)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ module VzaarApi
2
+ VERSION = '2.0.0'
3
+ UPLOADER = 'Ruby-2.0.0'
4
+ end
@@ -0,0 +1,38 @@
1
+ module VzaarApi
2
+ class Video < Abstract
3
+
4
+ ENDPOINT = 'videos'
5
+
6
+ ATTR_READERS = [:id, :user_id, :account_id, :categories,
7
+ :renditions, :legacy_renditions, :url,
8
+ :thumbnail_url, :state,
9
+ :created_at, :updated_at].freeze
10
+
11
+ ATTR_ACCESSORS = [:category_ids, :description, :private, :seo_url, :title].freeze
12
+
13
+ prepend Lib::HasAttributes
14
+ include Lib::HasResourceUrl
15
+ include Lib::ActiveObject::Find
16
+ include Lib::ActiveObject::Save
17
+ include Lib::ActiveObject::Delete
18
+ include Lib::WillPaginate
19
+
20
+ def initialize(attrs = {})
21
+ update_from_attributes attrs
22
+ end
23
+
24
+ def self.create(attrs = {})
25
+ Strategy::Video::Create.new(attrs, self).execute
26
+ end
27
+
28
+ private
29
+
30
+ def update_from_attributes(attrs)
31
+ @categories = Category.build(attrs[:categories])
32
+ @category_ids = @categories.map(&:id)
33
+ @renditions = Rendition.build(attrs[:renditions])
34
+ @legacy_renditions = LegacyRendition.build(attrs[:renditions])
35
+ end
36
+
37
+ end
38
+ end
data/lib/vzaar_api.rb ADDED
@@ -0,0 +1,60 @@
1
+ $: << File.dirname(__FILE__)
2
+
3
+ require 'forwardable'
4
+ require 'httpclient'
5
+ require 'json'
6
+
7
+ require 'vzaar_api/version'
8
+
9
+ require 'vzaar_api/lib/api'
10
+ require 'vzaar_api/lib/api_response'
11
+ require 'vzaar_api/lib/active_object'
12
+ require 'vzaar_api/lib/has_attributes'
13
+ require 'vzaar_api/lib/has_collection_builder'
14
+ require 'vzaar_api/lib/has_resource_url'
15
+ require 'vzaar_api/lib/paged_resource'
16
+ require 'vzaar_api/lib/will_paginate'
17
+
18
+ require 'vzaar_api/abstract'
19
+ require 'vzaar_api/category'
20
+ require 'vzaar_api/encoding_preset'
21
+ require 'vzaar_api/ingest_recipe'
22
+ require 'vzaar_api/legacy_rendition'
23
+ require 'vzaar_api/link_upload'
24
+ require 'vzaar_api/playlist'
25
+ require 'vzaar_api/rendition'
26
+ require 'vzaar_api/strategy/video/create'
27
+ require 'vzaar_api/video'
28
+
29
+ require 'vzaar_api/signature/abstract'
30
+ require 'vzaar_api/signature/factory'
31
+ require 'vzaar_api/signature/multipart'
32
+ require 'vzaar_api/signature/single'
33
+
34
+ require 'vzaar_api/upload/s3'
35
+ require 'vzaar_api/upload/virtual_file'
36
+
37
+ module VzaarApi
38
+ class Error < StandardError ; end
39
+
40
+ DEFAULT_HOSTNAME = 'api.vzaar.com'
41
+ DEFAULT_PROTOCOL = 'https'
42
+
43
+ class << self
44
+ attr_accessor :auth_token, :client_id, :hostname,
45
+ :rate_limit, :rate_limit_remaining, :rate_limit_reset
46
+
47
+ def hostname
48
+ @hostname || DEFAULT_HOSTNAME
49
+ end
50
+
51
+ def protocol
52
+ @protocol || DEFAULT_PROTOCOL
53
+ end
54
+
55
+ def protocol=(value)
56
+ @protocol = value.downcase == 'https' ? 'https' : 'http'
57
+ end
58
+ end
59
+
60
+ end