coconutrb 2.4.0 → 3.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 5d080f48508838a97c4a7aa3d7022008741ca5b2
4
- data.tar.gz: be3d0ec286c2d79774e68edec3b9c1634d1dd32b
2
+ SHA256:
3
+ metadata.gz: 7aa3f69b0c70c759598d976f4d17b5bd0fd7f6606af16d0963997357de1990f6
4
+ data.tar.gz: fc07ef5a74c85511ecd75d0f2e1d3106828ba843f887ff50a9f6274d868a44ad
5
5
  SHA512:
6
- metadata.gz: bd2260ce0933b9bbcc6906285c1fa3416caf08845e7ee4b30f22ed29c912e67dde5abe17b1c6b669072bcc281b216275f520496e7efd8f6d97de9030988c34b1
7
- data.tar.gz: 12825f9470666421d7dbbb5755f035eb818dd17454d9307cf6e83f71c94dd37f1755d5ed479cd631c17303d4a2fc4789befcfa4dd460b07353272a46daadc78a
6
+ metadata.gz: 640e39db9a079f9a77560a0c600c25debdab49e69db0c91e551f872a9060a8e6a1e90c0ad305c73df566d31d578fe6cce9cee431380f67c66fe63a0ed2aff419
7
+ data.tar.gz: 9ad2757fb32aee75a13051ad793483ba06c332519cdfb4638ef0fb5969e52c1b8b2e1e1b0e91d3083904b7a723f7e5d18b5380a5aa6ef0a0e1841da5fb78b530
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .DS_Store
2
+ .testenv
3
+ run_tests
4
+ *.gem
data/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # Coconut Ruby Library
2
+
3
+ The Coconut Ruby library provides access to the Coconut API for encoding videos, packaging media files into HLS and MPEG-Dash, generating thumbnails and GIF animation.
4
+
5
+ This library is only compatible with the Coconut API v2.
6
+
7
+ ## Documentation
8
+
9
+ See the [full documentation](https://docs.coconut.co).
10
+
11
+ ## Installation
12
+
13
+ You can install it via rubygems:
14
+
15
+ ```console
16
+ gem install coconutrb
17
+ ```
18
+
19
+ ### Bundler
20
+
21
+ In Gemfile:
22
+
23
+ ```ruby
24
+ gem 'coconutrb', '~> 3.0.0'
25
+ ```
26
+
27
+ And then, type in your terminal:
28
+
29
+ ```console
30
+ bundle install
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ The library needs you to set your API key which can be found in your [dashboard](https://app.coconut.co/api). Webhook URL and storage settings are optional but are very convenient because you set them only once.
36
+
37
+ ```ruby
38
+ Coconut.api_key = 'k-api-key'
39
+
40
+ Coconut.notification = {
41
+ type: "http",
42
+ url: "https://yoursite/api/coconut/webhook"
43
+ }
44
+
45
+ Coconut.storage = {
46
+ service: "s3",
47
+ bucket: "my-bucket",
48
+ region: "us-east-1",
49
+ credentials: {
50
+ access_key_id: "access-key",
51
+ secret_access_key: "secret-key"
52
+ }
53
+ }
54
+ ```
55
+
56
+ ## Creating a job
57
+
58
+ ```ruby
59
+ Coconut::Job.create(
60
+ input: { url: "https://mysite/path/file.mp4" },
61
+ outputs: {
62
+ "jpg:300x": { path: "/image.jpg" },
63
+ "mp4:1080p": { path: "/1080p.mp4" },
64
+ "httpstream": {
65
+ hls: { path: "hls/" }
66
+ }
67
+ }
68
+ )
69
+ ```
70
+
71
+ ## Getting information about a job
72
+
73
+ ```ruby
74
+ Coconut::Job.retrieve("OolQXaiU86NFki")
75
+ ```
76
+
77
+ ## Retrieving metadata
78
+
79
+ ```ruby
80
+ Coconut::Metadata.retrieve("OolQXaiU86NFki")
81
+
82
+ ```
83
+
84
+ ## Per-request configuration
85
+
86
+ ```ruby
87
+ cli = Coconut::Client.new(api_key: "k-api-key-prod")
88
+ Coconut::Job.create(job, client: cli)
89
+ ```
90
+
91
+ *Released under the [MIT license](http://www.opensource.org/licenses/mit-license.php).*
data/coconutrb.gemspec ADDED
@@ -0,0 +1,18 @@
1
+ $LOAD_PATH.unshift(::File.join(::File.dirname(__FILE__), "lib"))
2
+
3
+ require "coconut/version"
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "coconutrb"
7
+ gem.version = Coconut::VERSION
8
+ gem.summary = "Client library to transcode videos with coconut.co"
9
+ gem.description = "Official client library to transcode videos with Coconut Cloud Service"
10
+ gem.author = "Coconut"
11
+ gem.email = "support@coconut.co"
12
+ gem.homepage = "https://coconut.co"
13
+ gem.license = "MIT"
14
+ gem.files = `git ls-files`.split("\n")
15
+ gem.test_files = `git ls-files -- test/*`.split("\n")
16
+ gem.require_paths = ["lib"]
17
+ gem.add_runtime_dependency "http"
18
+ end
data/lib/coconut.rb ADDED
@@ -0,0 +1,50 @@
1
+ require "coconut/api"
2
+ require "coconut/error"
3
+ require "coconut/client"
4
+ require "coconut/job"
5
+ require "coconut/metadata"
6
+ require "coconut/version"
7
+
8
+ module Coconut
9
+ ENDPOINT = "https://api.coconut.co/v2"
10
+
11
+ def self.api_key=(key)
12
+ @api_key = key
13
+ end
14
+
15
+ def self.api_key
16
+ @api_key
17
+ end
18
+
19
+ def self.region=(region)
20
+ @region = region
21
+ end
22
+
23
+ def self.region
24
+ @region
25
+ end
26
+
27
+ def self.endpoint=(endpoint)
28
+ @endpoint = endpoint
29
+ end
30
+
31
+ def self.endpoint
32
+ @endpoint
33
+ end
34
+
35
+ def self.notification=(notification)
36
+ @notification = notification
37
+ end
38
+
39
+ def self.notification
40
+ @notification
41
+ end
42
+
43
+ def self.storage=(storage)
44
+ @storage = storage
45
+ end
46
+
47
+ def self.storage
48
+ @storage
49
+ end
50
+ end
@@ -0,0 +1,38 @@
1
+ require "http"
2
+
3
+ module Coconut
4
+ # Coconut::API is responsible for making API requests.
5
+ # It takes a Coconut::Client to send api_key, endpoint and region.
6
+ class API
7
+ def self.headers(cli)
8
+ if cli.api_key.nil?
9
+ raise Coconut::Error, "You must specify an API key with Coconut.api_key="
10
+ end
11
+
12
+ HTTP.basic_auth(user: cli.api_key, pass: "").
13
+ headers(:user_agent => "Coconut/v2 RubyBindings/#{Coconut::VERSION}")
14
+ end
15
+
16
+ def self.request(verb, path, options={})
17
+ cli = options[:client] || Coconut.default_client
18
+
19
+ case verb
20
+ when :get
21
+ resp = headers(cli).get("#{cli.endpoint}#{path}")
22
+ when :post
23
+ resp = headers(cli).post("#{cli.endpoint}#{path}", json: options[:json])
24
+ end
25
+
26
+ if resp.code > 399
27
+ # if response is 400 or 401, we return the error message and error code
28
+ if resp.code.between?(400, 401)
29
+ raise Coconut::Error, "#{resp.parse["message"]} (code=#{resp.parse["error_code"]})"
30
+ else
31
+ raise Coconut::Error, "Server returned HTTP status #{resp.code}."
32
+ end
33
+ end
34
+
35
+ return resp.parse
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ module Coconut
2
+ def self.default_client
3
+ Client.new({
4
+ api_key: Coconut.api_key,
5
+ region: Coconut.region,
6
+ endpoint: Coconut.endpoint
7
+ })
8
+ end
9
+
10
+ class Client
11
+ attr_accessor :api_key, :endpoint, :region
12
+
13
+ def initialize(options={})
14
+ @api_key = options[:api_key]
15
+ @region = options[:region]
16
+ @endpoint = options[:endpoint]
17
+ end
18
+
19
+ def endpoint
20
+ # if endpoint set, we return it
21
+ if @endpoint
22
+ return @endpoint
23
+ end
24
+ # if no endpoint but region is given, we
25
+ # build the endpoint following https://api-region.coconut.co/v2
26
+ if @region
27
+ return "https://api-#{@region}.coconut.co/v2"
28
+ end
29
+
30
+ # by default:
31
+ return Coconut::ENDPOINT
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module Coconut
2
+ class Error < RuntimeError; end
3
+ end
@@ -0,0 +1,42 @@
1
+ module Coconut
2
+ class Job < API
3
+ attr_reader :id, :created_at, :completed_at, :status, :progress, :errors, :output_urls
4
+
5
+ def initialize(attrs={})
6
+ @id = attrs["id"]
7
+ @created_at = attrs["created_at"]
8
+ @completed_at = attrs["completed_at"]
9
+ @status = attrs["status"]
10
+ @progress = attrs["progress"]
11
+ @errors = attrs["errors"]
12
+ @output_urls = attrs["output_urls"]
13
+ end
14
+
15
+ def self.retrieve(job_id, options={})
16
+ resp = API.request(:get, "/jobs/#{job_id}", options)
17
+ return Job.new(resp)
18
+ end
19
+
20
+ def self.create(job, options={})
21
+ resp = API.request(:post, "/jobs", options.merge({
22
+ json: apply_settings(job)
23
+ }))
24
+
25
+ return Job.new(resp)
26
+ end
27
+
28
+ def self.apply_settings(job)
29
+ if notification = Coconut.notification
30
+ job[:notification] ||= {}
31
+ job[:notification].merge!(notification)
32
+ end
33
+
34
+ if storage = Coconut.storage
35
+ job[:storage] ||= {}
36
+ job[:storage].merge!(storage)
37
+ end
38
+
39
+ return job
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,7 @@
1
+ module Coconut
2
+ class Metadata
3
+ def self.retrieve(job_id, options={})
4
+ API.request(:get, "/metadata/jobs/#{job_id}/#{options.delete(:key)}", options)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Coconut
2
+ VERSION = "3.0.0"
3
+ end
@@ -0,0 +1,90 @@
1
+ $LOAD_PATH.unshift(::File.join(::File.dirname(__FILE__), "..", "lib"))
2
+
3
+ require "test/unit"
4
+ require "coconut"
5
+
6
+ class CoconutTest < Test::Unit::TestCase
7
+ INPUT_URL = "https://s3-eu-west-1.amazonaws.com/files.coconut.co/bbb_800k.mp4"
8
+
9
+ def setup
10
+ Coconut.api_key = ENV["COCONUT_API_KEY"]
11
+ Coconut.endpoint = ENV["COCONUT_ENDPOINT"]
12
+
13
+ Coconut.storage = {
14
+ service: "s3",
15
+ region: ENV["AWS_REGION"],
16
+ credentials: { access_key_id: ENV["AWS_ACCESS_KEY_ID"], secret_access_key: ENV["AWS_SECRET_ACCESS_KEY"] },
17
+ bucket: ENV["AWS_BUCKET"],
18
+ path: "/coconutrb/tests/"
19
+ }
20
+
21
+ Coconut.notification = {
22
+ type: "http",
23
+ url: ENV["COCONUT_WEBHOOK_URL"]
24
+ }
25
+ end
26
+
27
+ def create_job(j={}, options={})
28
+ Coconut::Job.create({
29
+ input: { url: INPUT_URL },
30
+ outputs: {
31
+ mp4: { path: "/test_create_job.mp4", duration: 1 }
32
+ }
33
+ }.merge(j), options)
34
+ end
35
+
36
+ def test_coconut_api_key
37
+ Coconut.api_key = "apikey"
38
+ assert "apikey", Coconut.api_key
39
+ end
40
+
41
+ def test_coconut_region
42
+ Coconut.region = "us-east-1"
43
+ assert "us-east-1", Coconut.region
44
+ end
45
+
46
+ def test_coconut_default_endpoint
47
+ assert "https://api.coconut.co/v2", Coconut.endpoint
48
+ end
49
+
50
+ def test_coconut_endpoint_by_region
51
+ Coconut.region = "us-west-2"
52
+ assert "https://api-us-west-2.coconut.co/v2", Coconut.endpoint
53
+ end
54
+
55
+ def test_overwrite_endpoint
56
+ myendpoint = "https://coconut-private/v2"
57
+ Coconut.endpoint = myendpoint
58
+
59
+ assert myendpoint, Coconut.endpoint
60
+ end
61
+
62
+ def test_create_job
63
+ job = create_job
64
+ assert job.is_a?(Coconut::Job)
65
+ assert_not_nil job.id
66
+ assert_equal "job.starting", job.status
67
+ end
68
+
69
+ def test_retrieve_job
70
+ job = Coconut::Job.retrieve(create_job.id)
71
+ assert job.is_a?(Coconut::Job)
72
+ assert_not_nil job.id
73
+ assert_equal "job.starting", job.status
74
+ end
75
+
76
+ def test_create_job_error
77
+ create_job(input: {url: "notvalidurl"})
78
+ rescue => e
79
+ assert_equal e.class, Coconut::Error
80
+ end
81
+
82
+ def test_retrieve_metadata
83
+ job = create_job
84
+ sleep 10
85
+
86
+ md = Coconut::Metadata.retrieve(job.id)
87
+ assert md.is_a?(Hash)
88
+ assert_not_nil md["metadata"]["input"]
89
+ end
90
+ end
metadata CHANGED
@@ -1,37 +1,47 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coconutrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
- - Bruno Celeste
7
+ - Coconut
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-18 00:00:00.000000000 Z
11
+ date: 2021-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: multi_json
14
+ name: http
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
27
- description: Official client library to transcode videos with coconut cloud service
28
- email: bruno@coconut.co
26
+ version: '0'
27
+ description: Official client library to transcode videos with Coconut Cloud Service
28
+ email: support@coconut.co
29
29
  executables: []
30
30
  extensions: []
31
31
  extra_rdoc_files: []
32
32
  files:
33
- - lib/coconutrb.rb
34
- homepage: http://coconut.co
33
+ - ".gitignore"
34
+ - README.md
35
+ - coconutrb.gemspec
36
+ - lib/coconut.rb
37
+ - lib/coconut/api.rb
38
+ - lib/coconut/client.rb
39
+ - lib/coconut/error.rb
40
+ - lib/coconut/job.rb
41
+ - lib/coconut/metadata.rb
42
+ - lib/coconut/version.rb
43
+ - test/coconut_test.rb
44
+ homepage: https://coconut.co
35
45
  licenses:
36
46
  - MIT
37
47
  metadata: {}
@@ -50,9 +60,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
50
60
  - !ruby/object:Gem::Version
51
61
  version: '0'
52
62
  requirements: []
53
- rubyforge_project:
54
- rubygems_version: 2.5.2.3
63
+ rubygems_version: 3.1.4
55
64
  signing_key:
56
65
  specification_version: 4
57
66
  summary: Client library to transcode videos with coconut.co
58
- test_files: []
67
+ test_files:
68
+ - test/coconut_test.rb
data/lib/coconutrb.rb DELETED
@@ -1,135 +0,0 @@
1
- require "net/http"
2
- require "multi_json"
3
- require "uri"
4
-
5
- module Coconut
6
- class Error < RuntimeError; end
7
-
8
- COCONUT_URL = ENV["COCONUT_URL"] || "https://api.coconut.co"
9
- USER_AGENT = "Coconut/2.4.0 (Ruby)"
10
-
11
- API_KEY = ENV["COCONUT_API_KEY"] unless const_defined?(:COCONUT_API_KEY)
12
-
13
- def self.submit(config_content, api_key=nil)
14
- api_key ||= API_KEY
15
- uri = URI("#{COCONUT_URL}/v1/job")
16
- headers = {"User-Agent" => USER_AGENT, "Content-Type" => "text/plain", "Accept" => "application/json"}
17
-
18
- req = Net::HTTP::Post.new(uri.path, headers)
19
- req.basic_auth api_key, ''
20
- req.body = config_content
21
-
22
- response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme.include?("https")) do |http|
23
- http.request(req)
24
- end
25
-
26
- return MultiJson.decode(response.body)
27
- end
28
-
29
- def self.submit!(config_content, opts={})
30
- result = submit(config_content, opts)
31
- if result["status"] == "error"
32
- raise Error, "#{result["message"]} (#{result["error_code"]})"
33
- else
34
- return result
35
- end
36
- end
37
-
38
- def self.get(path, api_key=nil)
39
- api_key ||= API_KEY
40
- uri = URI("#{COCONUT_URL}#{path}")
41
- headers = {"User-Agent" => USER_AGENT, "Content-Type" => "text/plain", "Accept" => "application/json"}
42
-
43
- req = Net::HTTP::Get.new(uri.path, headers)
44
- req.basic_auth api_key, ''
45
-
46
- response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme.include?("https")) do |http|
47
- http.request(req)
48
- end
49
-
50
- if response.code.to_i != 200
51
- return nil
52
- else
53
- return MultiJson.decode(response.body)
54
- end
55
- end
56
-
57
- def self.config(options={})
58
- if conf_file = options[:conf]
59
- raise Error, "Config file `#{conf_file}' not found" if ! File.exists?(conf_file)
60
- conf = File.read(conf_file).strip.split("\n")
61
- else
62
- conf = []
63
- end
64
-
65
- if vars = options[:vars]
66
- vars.each do |name,value|
67
- conf << "var #{name} = #{value}"
68
- end
69
- end
70
-
71
- if source = options[:source]
72
- conf << "set source = #{source}"
73
- end
74
-
75
- if webhook = options[:webhook]
76
- if webhook.is_a?(Hash)
77
- webhook = hash_params_to_string(webhook)
78
- end
79
-
80
- conf << "set webhook = #{webhook}"
81
- end
82
-
83
- if api_version = options[:api_version]
84
- conf << "set api_version = #{api_version}"
85
- end
86
-
87
- if outputs = options[:outputs]
88
- outputs.each do |format, cdn|
89
- if cdn.is_a?(Hash)
90
- cdn = hash_params_to_string(cdn)
91
- end
92
-
93
- conf << "-> #{format} = #{cdn}"
94
- end
95
- end
96
-
97
- new_conf = []
98
-
99
- new_conf.concat conf.select{|l| l.start_with?("var")}.sort
100
- new_conf << ""
101
- new_conf.concat conf.select{|l| l.start_with?("set")}.sort
102
- new_conf << ""
103
- new_conf.concat conf.select{|l| l.start_with?("->")}.sort
104
-
105
- return new_conf.join("\n")
106
- end
107
-
108
- def self.hash_params_to_string(params)
109
- params.map{|k,v|
110
- if k.to_s == "url"
111
- "#{v}"
112
- else
113
- "#{k}=#{v}"
114
- end
115
- }.join(", ")
116
- end
117
-
118
- class Job
119
- def self.create(options={})
120
- Coconut.submit(Coconut.config(options), options[:api_key])
121
- end
122
-
123
- def self.get(jid, api_key=nil)
124
- Coconut.get("/v1/jobs/#{jid}", api_key)
125
- end
126
-
127
- def self.get_all_metadata(jid, api_key=nil)
128
- Coconut.get("/v1/metadata/jobs/#{jid}", api_key)
129
- end
130
-
131
- def self.get_metadata_for(jid, source_or_output, api_key=nil)
132
- Coconut.get("/v1/metadata/jobs/#{jid}/#{source_or_output}", api_key)
133
- end
134
- end
135
- end