ivona_speech_cloud 0.0.1
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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +22 -0
- data/README.md +61 -0
- data/Rakefile +2 -0
- data/ivona_speech_cloud.gemspec +24 -0
- data/lib/ivona_speech_cloud.rb +6 -0
- data/lib/ivona_speech_cloud/client.rb +112 -0
- data/lib/ivona_speech_cloud/create_speech.rb +24 -0
- data/lib/ivona_speech_cloud/input.rb +109 -0
- data/lib/ivona_speech_cloud/list_voices.rb +19 -0
- data/lib/ivona_speech_cloud/runner.rb +34 -0
- data/lib/ivona_speech_cloud/version.rb +3 -0
- data/spec/helper.rb +32 -0
- data/spec/ivona_speech_cloud/client_spec.rb +93 -0
- data/spec/ivona_speech_cloud/create_speech_spec.rb +42 -0
- data/spec/ivona_speech_cloud/input_spec.rb +24 -0
- data/spec/ivona_speech_cloud/list_voices_spec.rb +36 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fa5b6fdd6311fd2673dd00e724c9aaec56c42621
|
4
|
+
data.tar.gz: 29b07b32eddc562cd4c05c406da77da78e4d44b2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ee3f4495e4759d71591b7d01d6151c58cb2a5001e850d1689383fcc6a49e26574960faa95e1be000372e4f9e7ddd9e87f4b31fe42614e08698c66caa3a6ef222
|
7
|
+
data.tar.gz: 68cfd122a626fa01292a2a60243539c3be6173a676fcd38311e14cbdc8ad34dbb027b92fcfdaa9124789d2be801c7f6e80a95407b45a02fee85561fd8d0404c0
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Sergio Bayona
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# IvonaSpeechCloud
|
2
|
+
|
3
|
+
A Ruby client for Amazon's Text-to-Speech Service (Ivona Speech Cloud).
|
4
|
+
|
5
|
+
See: http://www.ivona.com/us/for-business/speech-cloud/
|
6
|
+
|
7
|
+
Speech Cloud documentation: http://developer.ivona.com/en/speechcloud/introduction.html
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'ivona_speech_cloud', github: "martianinteractive/ivona_speech_cloud"
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
## Setup
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
client = IvonaSpeechCloud::Client.new do |config|
|
25
|
+
config.access_key = "YOUR-ACCESS-KEY"
|
26
|
+
config.secret_key = "YOUR-SECRET-KEY"
|
27
|
+
config.region = "us-east-1"
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
## Creating Speech Files
|
32
|
+
|
33
|
+
```
|
34
|
+
client.create_speech('Hello world!')
|
35
|
+
```
|
36
|
+
|
37
|
+
You can pass a hash of options as the second argument, i.e:
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
client.create_speech('Hola mundo!', {language: "es-ES", gender: "Female", voice_name: "Conchita"})
|
41
|
+
```
|
42
|
+
|
43
|
+
## Listing Voices
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
client.list_voices
|
47
|
+
|
48
|
+
# => {"Voices"=>[{"Gender"=>"Female", "Language"=>"en-US", "Name"=>"Salli"},... ]}
|
49
|
+
|
50
|
+
client.list_voices({Language: "es-ES"})
|
51
|
+
|
52
|
+
# => {"Voices"=>[{"Gender"=>"Female", "Language"=>"es-ES", "Name"=>"Conchita"}, {"Gender"=>"Male", "Language"=>"es-ES", "Name"=>"Enrique"}]}
|
53
|
+
```
|
54
|
+
|
55
|
+
## Contributing
|
56
|
+
|
57
|
+
1. Fork it ( https://github.com/[my-github-username]/ivona_speech_cloud/fork )
|
58
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
59
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
60
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
61
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ivona_speech_cloud/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ivona_speech_cloud"
|
8
|
+
spec.version = IvonaSpeechCloud::VERSION
|
9
|
+
spec.authors = ["Sergio Bayona"]
|
10
|
+
spec.email = ["sergio@practicaldesk.com"]
|
11
|
+
spec.summary = %q{Interface for Ivona Speech Cloud.}
|
12
|
+
spec.description = %q{Ability to create speech and list voices.}
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
spec.add_dependency "aws4", "~> 0.0.2"
|
23
|
+
spec.add_dependency "httparty", "~> 0.13.5"
|
24
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'aws4'
|
2
|
+
require 'httparty'
|
3
|
+
|
4
|
+
module IvonaSpeechCloud
|
5
|
+
class Client
|
6
|
+
attr_accessor :access_key, :secret_key, :region, :body, :path
|
7
|
+
|
8
|
+
# Initializes a new Client object
|
9
|
+
#
|
10
|
+
# @param options [Hash]
|
11
|
+
# @return [IvonaSpeechCloud::Client]
|
12
|
+
def initialize(options = {})
|
13
|
+
options.each do |key, value|
|
14
|
+
instance_variable_set("@#{key}", value)
|
15
|
+
end
|
16
|
+
|
17
|
+
yield(self) if block_given?
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the audio representation of the text
|
21
|
+
#
|
22
|
+
# @param options [Array] A customizable set of options.
|
23
|
+
# @return [String]
|
24
|
+
def create_speech(*options)
|
25
|
+
CreateSpeech.new(self, options).run
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns a list of TTS voices available.
|
29
|
+
# The list can be filtered by passing a language and/or gender parameter.
|
30
|
+
#
|
31
|
+
# @param options [Hash]
|
32
|
+
# @return [Hash]
|
33
|
+
def list_voices(options)
|
34
|
+
ListVoices.new(self, options).run
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Hash]
|
38
|
+
def credentials
|
39
|
+
{
|
40
|
+
access_key: access_key,
|
41
|
+
secret_key: secret_key,
|
42
|
+
region: region
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [URI::HTTPS]
|
47
|
+
def uri
|
48
|
+
@uri = begin
|
49
|
+
uri = URI(endpoint)
|
50
|
+
uri.path = path if path
|
51
|
+
uri
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [String]
|
56
|
+
def endpoint
|
57
|
+
"https://#{host}"
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [String]
|
61
|
+
def host
|
62
|
+
"tts.#{region}.ivonacloud.com"
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [String]
|
66
|
+
def x_amz_date
|
67
|
+
date.strftime("%Y%m%dT%H%M%SZ")
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Time]
|
71
|
+
def date
|
72
|
+
@date ||= Time.now.utc
|
73
|
+
end
|
74
|
+
|
75
|
+
# @param body [String]
|
76
|
+
# @return [String]
|
77
|
+
def x_amz_content_sha256(body="")
|
78
|
+
Digest::SHA256.new.update(body).hexdigest
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [String]
|
82
|
+
def content_type
|
83
|
+
"application/json"
|
84
|
+
end
|
85
|
+
|
86
|
+
# @return [Hash]
|
87
|
+
def signed_headers
|
88
|
+
signer.sign("POST", uri, headers, body)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [AWS4::Signer]
|
92
|
+
def signer
|
93
|
+
@signer ||= AWS4::Signer.new(credentials)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [Hash]
|
97
|
+
def headers
|
98
|
+
@headers ||= {
|
99
|
+
"Content-Type" => content_type,
|
100
|
+
"Host" => host,
|
101
|
+
"X-Amz-Content-SHA256" => x_amz_content_sha256,
|
102
|
+
"X-Amz-Date" => x_amz_date
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
# @return [Boolean]
|
107
|
+
def credentials?
|
108
|
+
credentials.values.all?
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module IvonaSpeechCloud
|
2
|
+
class CreateSpeech
|
3
|
+
attr_accessor :options
|
4
|
+
|
5
|
+
include Runner
|
6
|
+
|
7
|
+
# Initializes a new CreateSpeech object
|
8
|
+
# options example:
|
9
|
+
# ["Hello world!"]
|
10
|
+
# ["Hello world!", {:voice_name => "Joey"}]
|
11
|
+
# ["Bonjour le monde", {:gender => "Female", :language => "fr-FR", :voice_name => "Celine"}]
|
12
|
+
#
|
13
|
+
# @param client [IvonaSpeechCloud::Client]
|
14
|
+
# @param text [String]
|
15
|
+
# @param options [Array]
|
16
|
+
# @return [IvonaSpeechCloud::CreateSpeech]
|
17
|
+
def initialize(client, options)
|
18
|
+
@client = client
|
19
|
+
@options = options
|
20
|
+
@path = "/CreateSpeech"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module IvonaSpeechCloud
|
2
|
+
|
3
|
+
module Input
|
4
|
+
|
5
|
+
DEFAULT = {
|
6
|
+
:codec => "MP3",
|
7
|
+
:sample_rate => 22050,
|
8
|
+
:rate => "medium",
|
9
|
+
:volume => "medium",
|
10
|
+
:sentence_break => 500,
|
11
|
+
:paragraph_break => 800,
|
12
|
+
:voice_name => "Salli",
|
13
|
+
:language => "en-US",
|
14
|
+
:gender => "Female"
|
15
|
+
}
|
16
|
+
|
17
|
+
module CommonDefaults
|
18
|
+
def language
|
19
|
+
options.fetch(:language, DEFAULT[:language])
|
20
|
+
end
|
21
|
+
|
22
|
+
def gender
|
23
|
+
options.fetch(:gender, DEFAULT[:gender])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class CreateSpeech
|
28
|
+
include CommonDefaults
|
29
|
+
|
30
|
+
attr_accessor :text, :options
|
31
|
+
|
32
|
+
# @param options [Array]
|
33
|
+
def initialize(options)
|
34
|
+
@text = options.first
|
35
|
+
@options = options.last.is_a?(Hash) ? options.pop : {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def params
|
39
|
+
{
|
40
|
+
"Input" => {
|
41
|
+
"Data" => text
|
42
|
+
},
|
43
|
+
"OutputFormat" => {
|
44
|
+
"Codec" => codec,
|
45
|
+
"SampleRate" => sample_rate,
|
46
|
+
},
|
47
|
+
"Parameters" => {
|
48
|
+
"Rate" => rate,
|
49
|
+
"Volume" => volume,
|
50
|
+
"SentenceBreak" => sentence_break,
|
51
|
+
"ParagraphBreak" => paragraph_break
|
52
|
+
},
|
53
|
+
"Voice" => {
|
54
|
+
"Name" => voice_name,
|
55
|
+
"Language" => language,
|
56
|
+
"Gender" => gender
|
57
|
+
}
|
58
|
+
}.to_json
|
59
|
+
end
|
60
|
+
|
61
|
+
def codec
|
62
|
+
options.fetch(:codec, DEFAULT[:codec])
|
63
|
+
end
|
64
|
+
|
65
|
+
def sample_rate
|
66
|
+
options.fetch(:sample_rate, DEFAULT[:sample_rate])
|
67
|
+
end
|
68
|
+
|
69
|
+
def rate
|
70
|
+
options.fetch(:rate, DEFAULT[:rate])
|
71
|
+
end
|
72
|
+
|
73
|
+
def volume
|
74
|
+
options.fetch(:volume, DEFAULT[:volume])
|
75
|
+
end
|
76
|
+
|
77
|
+
def sentence_break
|
78
|
+
options.fetch(:sentence_break, DEFAULT[:sentence_break])
|
79
|
+
end
|
80
|
+
|
81
|
+
def paragraph_break
|
82
|
+
options.fetch(:paragraph_break, DEFAULT[:paragraph_break])
|
83
|
+
end
|
84
|
+
|
85
|
+
def voice_name
|
86
|
+
options.fetch(:voice_name, DEFAULT[:voice_name])
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
class ListVoices
|
92
|
+
attr_accessor :options
|
93
|
+
|
94
|
+
include CommonDefaults
|
95
|
+
|
96
|
+
def initialize(options)
|
97
|
+
@options = options.first.is_a?(Hash) ? options.first : {}
|
98
|
+
end
|
99
|
+
|
100
|
+
def params
|
101
|
+
{
|
102
|
+
"Voice" => {
|
103
|
+
"Language" => language
|
104
|
+
}.merge(options)
|
105
|
+
}.to_json
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module IvonaSpeechCloud
|
2
|
+
class ListVoices
|
3
|
+
attr_accessor :options
|
4
|
+
|
5
|
+
include Runner
|
6
|
+
|
7
|
+
# Initializes a new Voice object
|
8
|
+
#
|
9
|
+
# @param client [IvonaSpeechCloud::Client]
|
10
|
+
# @param options [Hash]
|
11
|
+
# @return [IvonaSpeechCloud::Voice]
|
12
|
+
def initialize(client, *options)
|
13
|
+
@client = client
|
14
|
+
@options = options
|
15
|
+
@path = "/ListVoices"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module IvonaSpeechCloud
|
2
|
+
module Runner
|
3
|
+
|
4
|
+
# @return [HTTParty::Response]
|
5
|
+
def run
|
6
|
+
@client.path = @path
|
7
|
+
@client.body = input
|
8
|
+
perform_post
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [Hash]
|
12
|
+
def input
|
13
|
+
@input ||= eval(input_class).new(options).params
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [String]
|
17
|
+
def input_class
|
18
|
+
caller = self.class.to_s.split("::").last
|
19
|
+
@input_class = "Input::#{caller}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# @return [HTTParty::Response]
|
25
|
+
def perform_post
|
26
|
+
post_options = {
|
27
|
+
body: input,
|
28
|
+
headers: @client.signed_headers
|
29
|
+
}
|
30
|
+
|
31
|
+
HTTParty.post(@client.uri, post_options)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'ivona_speech_cloud'
|
2
|
+
require 'rspec'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
WebMock.disable_net_connect!
|
7
|
+
|
8
|
+
def client_instance
|
9
|
+
IvonaSpeechCloud::Client.new do |config|
|
10
|
+
config.access_key = "YOUR-ACCESS-KEY"
|
11
|
+
config.secret_key = "YOUR-SECRET-KEY"
|
12
|
+
config.region = "us-east-1"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def stub_create_speech_request
|
17
|
+
stub_request(:post, "https://tts.us-east-1.ivonacloud.com/CreateSpeech").
|
18
|
+
with(:body => "{\"Input\":{\"Data\":\"hello world!\"},\"OutputFormat\":{\"Codec\":\"MP3\",\"SampleRate\":22050},\"Parameters\":{\"Rate\":\"medium\",\"Volume\":\"medium\",\"SentenceBreak\":500,\"ParagraphBreak\":800},\"Voice\":{\"Name\":\"Salli\",\"Language\":\"en-US\",\"Gender\":\"Female\"}}").
|
19
|
+
to_return(:status => 200, :body => "", :headers => {})
|
20
|
+
end
|
21
|
+
|
22
|
+
def stub_list_voices_request
|
23
|
+
stub_request(:post, "https://tts.us-east-1.ivonacloud.com/ListVoices").
|
24
|
+
with(:body => "{\"Voice\":{\"Language\":\"en-US\"}}").
|
25
|
+
to_return(:status => 200, :body => "", :headers => {})
|
26
|
+
end
|
27
|
+
|
28
|
+
def stub_create_speech_request_with_options
|
29
|
+
stub_request(:post, "https://tts.us-east-1.ivonacloud.com/CreateSpeech").
|
30
|
+
with(:body => "{\"Input\":{\"Data\":\"hola mundo!\"},\"OutputFormat\":{\"Codec\":\"MP3\",\"SampleRate\":22050},\"Parameters\":{\"Rate\":\"medium\",\"Volume\":\"medium\",\"SentenceBreak\":500,\"ParagraphBreak\":800},\"Voice\":{\"Name\":\"Enrique\",\"Language\":\"es-ES\",\"Gender\":\"Male\"}}").
|
31
|
+
to_return(:status => 200, :body => "", :headers => {})
|
32
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe IvonaSpeechCloud::Client do
|
4
|
+
|
5
|
+
subject { client_instance }
|
6
|
+
|
7
|
+
it { expect(subject.access_key).to eq "YOUR-ACCESS-KEY" }
|
8
|
+
|
9
|
+
it { expect(subject.secret_key).to eq "YOUR-SECRET-KEY" }
|
10
|
+
|
11
|
+
it { expect(subject.region).to eq "us-east-1" }
|
12
|
+
|
13
|
+
it "returns the credentials" do
|
14
|
+
expect(subject.credentials).to eq ({
|
15
|
+
access_key: "YOUR-ACCESS-KEY",
|
16
|
+
secret_key: "YOUR-SECRET-KEY",
|
17
|
+
region: "us-east-1"
|
18
|
+
})
|
19
|
+
end
|
20
|
+
|
21
|
+
it { expect(subject.credentials?).to eq true }
|
22
|
+
|
23
|
+
it { expect(subject.uri.host).to eq "tts.us-east-1.ivonacloud.com" }
|
24
|
+
|
25
|
+
it { expect(subject.uri.path).to eq "" }
|
26
|
+
|
27
|
+
it { expect(subject.endpoint).to eq "https://tts.us-east-1.ivonacloud.com" }
|
28
|
+
|
29
|
+
it { expect(subject.host).to eq "tts.us-east-1.ivonacloud.com" }
|
30
|
+
|
31
|
+
it { expect(subject.x_amz_date).to eq subject.date.strftime("%Y%m%dT%H%M%SZ") }
|
32
|
+
|
33
|
+
it { expect(subject.content_type).to eq "application/json" }
|
34
|
+
|
35
|
+
it { expect(subject.x_amz_content_sha256).to eq Digest::SHA256.new.update("").hexdigest }
|
36
|
+
|
37
|
+
it { expect(subject.signer).to be_a AWS4::Signer }
|
38
|
+
|
39
|
+
context "#headers" do
|
40
|
+
|
41
|
+
it { expect(subject.headers["Content-Type"]).to eq 'application/json' }
|
42
|
+
|
43
|
+
it { expect(subject.headers["Host"]).to eq subject.host }
|
44
|
+
|
45
|
+
it { expect(subject.headers["X-Amz-Content-SHA256"]).to eq subject.x_amz_content_sha256 }
|
46
|
+
|
47
|
+
it { expect(subject.headers["X-Amz-Date"]).to eq subject.x_amz_date }
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
context "#signed_headers" do
|
52
|
+
it { expect(subject.signed_headers["Content-Type"]).to eq 'application/json' }
|
53
|
+
|
54
|
+
it { expect(subject.signed_headers["Host"]).to eq subject.host }
|
55
|
+
|
56
|
+
it { expect(subject.signed_headers["X-Amz-Content-SHA256"]).to eq subject.x_amz_content_sha256 }
|
57
|
+
|
58
|
+
it { expect(subject.signed_headers["X-Amz-Date"]).to eq subject.x_amz_date }
|
59
|
+
|
60
|
+
it { expect(subject.signed_headers.has_key?("Authorization")).to eq true }
|
61
|
+
end
|
62
|
+
|
63
|
+
context "#create_speech" do
|
64
|
+
|
65
|
+
before {stub_create_speech_request}
|
66
|
+
|
67
|
+
it { expect(subject.create_speech("hello world!").class.name).to eq "HTTParty::Response" }
|
68
|
+
|
69
|
+
it "changes the path to /CreateSpeech" do
|
70
|
+
expect {
|
71
|
+
subject.create_speech("hello world!")
|
72
|
+
}.to change {subject.path }.from(nil).to('/CreateSpeech')
|
73
|
+
end
|
74
|
+
|
75
|
+
it "changes the body to a string representation of the JSON payload" do
|
76
|
+
expect {
|
77
|
+
subject.create_speech("hello world!")
|
78
|
+
}.to change { subject.body }.from(nil).to("{\"Input\":{\"Data\":\"hello world!\"},\"OutputFormat\":{\"Codec\":\"MP3\",\"SampleRate\":22050},\"Parameters\":{\"Rate\":\"medium\",\"Volume\":\"medium\",\"SentenceBreak\":500,\"ParagraphBreak\":800},\"Voice\":{\"Name\":\"Salli\",\"Language\":\"en-US\",\"Gender\":\"Female\"}}")
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context "#create_speech with options" do
|
84
|
+
before { stub_create_speech_request_with_options }
|
85
|
+
|
86
|
+
it "modifies the request params with the specified options" do
|
87
|
+
options = {:gender => "Male", :language => "es-ES", :voice_name => "Enrique"}
|
88
|
+
|
89
|
+
expect(subject.create_speech("hola mundo!", options).class.name).to eq "HTTParty::Response"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe IvonaSpeechCloud::CreateSpeech do
|
4
|
+
|
5
|
+
let(:client) { client_instance }
|
6
|
+
|
7
|
+
subject { IvonaSpeechCloud::CreateSpeech.new(client, ["hello world!"]) }
|
8
|
+
|
9
|
+
it { expect(subject.options).to eq ["hello world!"] }
|
10
|
+
|
11
|
+
context "#create" do
|
12
|
+
before { stub_create_speech_request }
|
13
|
+
|
14
|
+
it "returns an HTTParty response" do
|
15
|
+
expect(subject.run.class).to eq HTTParty::Response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "#input" do
|
20
|
+
it "contains the input data" do
|
21
|
+
json_input = JSON(subject.input)
|
22
|
+
|
23
|
+
expect(json_input["Input"]).to eq({"Data" => "hello world!"})
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when initialized with options" do
|
27
|
+
let(:speech_with_options) { IvonaSpeechCloud::CreateSpeech.new(client, ["hello world!", {codec: "OGG"}]) }
|
28
|
+
|
29
|
+
it { expect(speech_with_options.options).to eq ["hello world!", {:codec=>"OGG"}] }
|
30
|
+
|
31
|
+
it "sets the input with the passed options" do
|
32
|
+
json_input = JSON(speech_with_options.input)
|
33
|
+
|
34
|
+
expect(json_input["OutputFormat"]).to eq({
|
35
|
+
"Codec" => "OGG",
|
36
|
+
"SampleRate" => 22050
|
37
|
+
})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe IvonaSpeechCloud::Input::CreateSpeech do
|
4
|
+
|
5
|
+
subject { IvonaSpeechCloud::Input::CreateSpeech.new(["hello world!"]) }
|
6
|
+
|
7
|
+
it { expect(subject.text).to eq "hello world!" }
|
8
|
+
|
9
|
+
it { expect(subject.options).to eq Hash.new }
|
10
|
+
|
11
|
+
describe "with options" do
|
12
|
+
subject { IvonaSpeechCloud::Input::CreateSpeech.new(["Hello world!", {codec: "OGG"}]) }
|
13
|
+
|
14
|
+
it { expect(subject.codec).to eq "OGG" }
|
15
|
+
|
16
|
+
it { expect(subject.options).to eq({codec: "OGG"}) }
|
17
|
+
|
18
|
+
it { expect(JSON(subject.params)["OutputFormat"]).to eq({
|
19
|
+
"Codec" => "OGG",
|
20
|
+
"SampleRate" => 22050
|
21
|
+
})
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe IvonaSpeechCloud::ListVoices do
|
4
|
+
|
5
|
+
let(:client) { client_instance }
|
6
|
+
|
7
|
+
subject { IvonaSpeechCloud::ListVoices.new(client) }
|
8
|
+
|
9
|
+
it { expect(subject.options).to eq [] }
|
10
|
+
|
11
|
+
context "#create" do
|
12
|
+
before { stub_list_voices_request }
|
13
|
+
|
14
|
+
it "returns an HTTParty response" do
|
15
|
+
expect(subject.run.class).to eq HTTParty::Response
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "#input" do
|
20
|
+
it "contains the input data" do
|
21
|
+
json_input = JSON(subject.input)
|
22
|
+
|
23
|
+
expect(json_input["Voice"]).to eq({"Language" => "en-US"})
|
24
|
+
end
|
25
|
+
|
26
|
+
context "with explict language option" do
|
27
|
+
subject { IvonaSpeechCloud::ListVoices.new(client, {:Language => "es-ES"}) }
|
28
|
+
|
29
|
+
it "" do
|
30
|
+
json_input = JSON(subject.input)
|
31
|
+
|
32
|
+
expect(json_input["Voice"]).to eq({"Language" => "es-ES"})
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ivona_speech_cloud
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sergio Bayona
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: aws4
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.0.2
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.0.2
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: httparty
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.13.5
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.13.5
|
69
|
+
description: Ability to create speech and list voices.
|
70
|
+
email:
|
71
|
+
- sergio@practicaldesk.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- ivona_speech_cloud.gemspec
|
82
|
+
- lib/ivona_speech_cloud.rb
|
83
|
+
- lib/ivona_speech_cloud/client.rb
|
84
|
+
- lib/ivona_speech_cloud/create_speech.rb
|
85
|
+
- lib/ivona_speech_cloud/input.rb
|
86
|
+
- lib/ivona_speech_cloud/list_voices.rb
|
87
|
+
- lib/ivona_speech_cloud/runner.rb
|
88
|
+
- lib/ivona_speech_cloud/version.rb
|
89
|
+
- spec/helper.rb
|
90
|
+
- spec/ivona_speech_cloud/client_spec.rb
|
91
|
+
- spec/ivona_speech_cloud/create_speech_spec.rb
|
92
|
+
- spec/ivona_speech_cloud/input_spec.rb
|
93
|
+
- spec/ivona_speech_cloud/list_voices_spec.rb
|
94
|
+
homepage:
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubyforge_project:
|
114
|
+
rubygems_version: 2.4.7
|
115
|
+
signing_key:
|
116
|
+
specification_version: 4
|
117
|
+
summary: Interface for Ivona Speech Cloud.
|
118
|
+
test_files:
|
119
|
+
- spec/helper.rb
|
120
|
+
- spec/ivona_speech_cloud/client_spec.rb
|
121
|
+
- spec/ivona_speech_cloud/create_speech_spec.rb
|
122
|
+
- spec/ivona_speech_cloud/input_spec.rb
|
123
|
+
- spec/ivona_speech_cloud/list_voices_spec.rb
|