vocalware 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4a00fc81a9d6dde4488d2b51d17bf9ebd35d0132
4
+ data.tar.gz: 8b930de1d5e591a8516a12720d714532571a0c93
5
+ SHA512:
6
+ metadata.gz: 99f87cc818f7c778673254b66abe5b562c98ec9a9dea8c638331c038b21d236466399638097abe8cb91d2e382765b3f7da12b09b443f31844ba9dead1ceacf0a
7
+ data.tar.gz: 786b3fcea77f7464a61513fa3daa9071d1a4298bd885e44798a1c846c8213601faf79e5e31cf66e588a60d0e7f8befe0fa483f464cbf6a5cd9b84eb190a5cda8
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 TMX Credit, author Sergey Potapov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,67 @@
1
+ # Vocalware
2
+
3
+ [![Build Status](https://travis-ci.org/TMXCredit/vocalware.png?branch=master)](https://travis-ci.org/TMXCredit/vocalware)
4
+
5
+ Ruby client for the [Vocalware](https://www.vocalware.com/) REST API.
6
+
7
+ ## Install
8
+
9
+ Add vocalware to your Gemfile:
10
+
11
+ ```ruby
12
+ gem 'vocalware'
13
+ ```
14
+
15
+ Run `bundle install`.
16
+
17
+ ## Usage
18
+
19
+ Lookup a voice by its attributes:
20
+
21
+ ```ruby
22
+ voice = Vocalware::Voice.find(:lang => :en, :name => 'Kate')
23
+ ```
24
+ As attributes you can also use `engine_id`, `lang_id`, `voice_id`, `gender`.
25
+
26
+ Initialize a client:
27
+
28
+ ```ruby
29
+ client = Vocalware::Client.new(
30
+ :secret_phrase => SECRET_PHRASE,
31
+ :api_id => API_ID,
32
+ :account_id => ACCOUNT_ID,
33
+ :voice => voice
34
+ )
35
+ ```
36
+
37
+ Generate speech from text:
38
+
39
+ ```ruby
40
+ audio_data = client.gen('Say hello on a night like this!')
41
+ File.binwrite('./cure.mp3', audio_data)
42
+ ```
43
+
44
+ ### Override attributes for a single request
45
+
46
+ If you need to say few words in Spanish, you can override the `:voice`
47
+ attribute for one single request:
48
+
49
+ ```
50
+ voice = Vocalware::Vocalware.find(:lang => :es, :name => 'Juan')
51
+ client.gen('Hola! Qué tal estás?', :voice => voice)
52
+ ```
53
+
54
+ ## Running tests
55
+
56
+ ```sh
57
+ rake spec
58
+ ```
59
+
60
+
61
+ ## Credits
62
+
63
+ * [Sergey Potapov](https://github.com/greyblake)
64
+
65
+ ## Copyright
66
+
67
+ Copyright (c) 2013 TMX Credit. See LICENSE.txt for further details.
@@ -0,0 +1,83 @@
1
+ engine_id , lang , name , voice_id , gender , description
2
+ 2 , en , Susan , 1 , F , US
3
+ 2 , en , Dave , 2 , M , US
4
+ 2 , en , Elizabeth , 4 , F , UK
5
+ 2 , en , Simon , 5 , M , UK
6
+ 2 , en , Catherine , 6 , F , UK
7
+ 2 , en , Allison , 7 , F , US
8
+ 2 , en , Steven , 8 , M , US
9
+ 2 , en , Alan , 9 , M , Australian
10
+ 2 , en , Grace , 10 , F , Australian
11
+ 2 , en , Veena , 11 , F , Indian
12
+ 2 , es , Carmen , 1 , F , Castilian
13
+ 2 , es , Juan , 2 , M , Castilian
14
+ 2 , es , Francisca , 3 , F , Chilean
15
+ 2 , es , Diego , 4 , M , Argentine
16
+ 2 , es , Esperanza , 5 , F , Mexican
17
+ 2 , es , Jorge , 6 , M , Castilian
18
+ 2 , es , Carlos , 7 , M , American
19
+ 2 , es , Soledad , 8 , F , American
20
+ 2 , es , Leonor , 9 , F , Castilian
21
+ 2 , es , Ximena , 10 , F , American
22
+ 2 , de , Stefan , 2 , M
23
+ 2 , de , Katrin , 3 , F
24
+ 2 , fr , Bernard , 2 , M , European
25
+ 2 , fr , Jolie , 3 , F , European
26
+ 2 , fr , Florence , 4 , F , European
27
+ 2 , fr , Charlotte , 5 , F , Canadian
28
+ 2 , fr , Olivier , 6 , M , Canadian
29
+ 2 , ca , Montserrat , 1 , F
30
+ 2 , ca , Jordi , 2 , M
31
+ 2 , ca , Empar , 3 , F , Valencian
32
+ 2 , pt , Gabriela , 1 , F , Brasilian
33
+ 2 , pt , Amalia , 2 , F , European
34
+ 2 , pt , Eusebio , 3 , M , European
35
+ 2 , pt , Fernanda , 4 , F , Brazilian
36
+ 2 , pt , Felipe , 5 , M , Brazilian
37
+ 2 , it , Paola , 1 , F
38
+ 2 , it , Silvana , 2 , F
39
+ 2 , it , Valentia , 3 , F
40
+ 2 , it , Luca , 5 , M
41
+ 2 , it , Marcello , 6 , M
42
+ 2 , it , Roberto , 7 , M
43
+ 2 , it , Matteo , 8 , M
44
+ 2 , it , Giulia , 9 , F
45
+ 2 , it , Federica , 10 , F
46
+ 2 , el , Afroditi , 1 , F
47
+ 2 , el , Nikos , 3 , M
48
+ 2 , sv , Annika , 1 , F
49
+ 2 , sv , Sven , 2 , M
50
+ 2 , zh , Linlin , 1 , F , Mandarin
51
+ 2 , zh , Lisheng , 2 , F , Mandarin
52
+ 2 , nl , Willem , 1 , M
53
+ 2 , nl , Saskia , 2 , F
54
+ 2 , pl , Zosia , 1 , F
55
+ 2 , pl , Krzysztof , 2 , M
56
+ 2 , gl , Carmela , 1 , F
57
+ 2 , tr , Kerem , 1 , M
58
+ 2 , tr , Zeynep , 2 , F
59
+ 2 , tr , Selin , 3 , F
60
+ 2 , da , Frida , 1 , F
61
+ 2 , da , Magnus , 2 , M
62
+ 2 , no , Vilde , 1 , F
63
+ 2 , no , Henrik , 2 , M
64
+ 2 , ru , Olga , 1 , F
65
+ 2 , ru , Dmitri , 2 , M
66
+ 2 , fi , Milla , 1 , F
67
+ 2 , fi , Marko , 2 , M
68
+ 2 , ar , Tarik , 1 , M
69
+ 2 , ar , Laila , 2 , F
70
+ 2 , ro , Ioana , 1 , F
71
+ 2 , eo , Ludoviko , 1 , M
72
+ 3 , en , Kate , 1 , F , US
73
+ 3 , en , Paul , 2 , M , US
74
+ 3 , en , Julie , 3 , F , US
75
+ 3 , en , Bridget , 4 , F , UK
76
+ 3 , es , Violeta , 1 , F
77
+ 3 , zh , Lily , 1 , F , Mandarin
78
+ 3 , zh , Hui , 3 , F , Mandarin
79
+ 3 , zh , Liang , 4 , M , Mandarin
80
+ 3 , ja , Show , 2 , M
81
+ 3 , ja , Misaki , 3 , F
82
+ 3 , ko , Yumi , 1 , F
83
+ 3 , ko , Junwoo , 2 , M
@@ -0,0 +1,24 @@
1
+ # Standard library
2
+ require 'csv'
3
+ require 'digest'
4
+ require 'cgi'
5
+
6
+ # Gems
7
+ require 'faraday'
8
+
9
+ # Vocalware
10
+ require 'vocalware/errors'
11
+ require 'vocalware/client'
12
+ require 'vocalware/languages'
13
+ require 'vocalware/voice'
14
+ require 'vocalware/request'
15
+
16
+
17
+ # Client for Vocalware REST API.
18
+ module Vocalware
19
+ # Path to directory with data.
20
+ DATA_PATH = File.expand_path('../../data', __FILE__)
21
+
22
+ # Path to CSV file with voices information.
23
+ VOICES_CSV_FILE = File.join(DATA_PATH, 'voices.csv')
24
+ end
@@ -0,0 +1,158 @@
1
+ module Vocalware
2
+ # Vocalware client, which uses Vocalware's REST API to generate speech.
3
+ #
4
+ # @example
5
+ # # Look up voice
6
+ # voice = Vocalware::Voice.find(:lang => :en, :name => 'Kate')
7
+ #
8
+ # # Initialize client
9
+ # client =
10
+ # Vocalware::Client.new(
11
+ # :secret_phrase => SECRET_PHRASE,
12
+ # :api_id => API_ID,
13
+ # :account_id => ACCOUNT_ID,
14
+ # :voice => voice
15
+ # )
16
+ #
17
+ # # Generate mp3
18
+ # client.gen("I love ruby!") # => mp3 audio as binary string
19
+ class Client
20
+ # @attribute account_id [Integer, String] account id (ACC)
21
+ attr_accessor :account_id
22
+
23
+ # @attribute api_id [Integer, String] API id (API)
24
+ attr_accessor :api_id
25
+
26
+ # @attribute secret_phrase [String] secret phrase
27
+ attr_accessor :secret_phrase
28
+
29
+ # @attribute voice [Vocalware::Voice] voice
30
+ attr_accessor :voice
31
+
32
+ # @attribute ext [String] whether "mp3" or "swf"
33
+ attr_accessor :ext
34
+
35
+ # @attribute host [String] host to which request will be set
36
+ attr_accessor :host
37
+
38
+ # @attribute path [String] path as part of URL to send request
39
+ attr_accessor :path
40
+
41
+ # @attribute protocol [String] whether "http" or "https"
42
+ attr_accessor :protocol
43
+
44
+ # @attribute port [Integer]
45
+ attr_accessor :port
46
+
47
+ # @attribute http_client [Faraday::Connection]
48
+ attr_accessor :http_client
49
+
50
+
51
+ # Default attributes
52
+ DEFAULT_ATTRS = {
53
+ :protocol => 'http',
54
+ :host => 'www.vocalware.com',
55
+ :path => '/tts/gen.php',
56
+ :ext => 'mp3'
57
+ }
58
+
59
+ # @param attrs [Hash<Symbol, Object>] client attributes
60
+ def initialize(attrs = {})
61
+ DEFAULT_ATTRS.merge(attrs).each do |attr_name, value|
62
+ send("#{attr_name}=", value)
63
+ end
64
+
65
+ @http_client ||= Faraday.new
66
+ validate!
67
+ end
68
+
69
+ # Generate speech from passed text.
70
+ #
71
+ # @param text [String] text to generate speech
72
+ # @param opts [Hash<Symbol, Object>] options which override client
73
+ # attributes for one particular request.
74
+ #
75
+ # @return [String] audio data in format defined by +:ext+ attribute
76
+ def gen(text, opts = {})
77
+ url = build_url(text, opts)
78
+ send_request(url)
79
+ end
80
+
81
+ # Build URL where request will be sent.
82
+ #
83
+ # @param text [String] text to generate speech
84
+ # @param opts [Hash<Symbol, Object>] options which override client
85
+ # attributes
86
+ #
87
+ # @return [String] url
88
+ def build_url(text, opts = {})
89
+ attrs = to_hash.merge(opts)
90
+ attrs[:text] = text.strip
91
+ Request.new(attrs).to_url
92
+ end
93
+
94
+
95
+ # Issue request to the remote service using HTTP client.
96
+ # Handle potential errors and raise {Vocalware::RequestError} with
97
+ # request information.
98
+ #
99
+ # @param url [String] end point with encoded GET parameters to send request
100
+ #
101
+ # @return [String] audio data
102
+ def send_request(url)
103
+ response = @http_client.get(url)
104
+
105
+ # If response has other status than success
106
+ unless response.status.between?(200, 299)
107
+ raise RequestError.from_url_and_response(
108
+ url, response, "Unexpected response status"
109
+ )
110
+ end
111
+
112
+ response_body = response.body
113
+
114
+ # In case of an error, Vocalware still returns a 200 HTTP status,
115
+ # but with an error message in the response body, instead of audio data.
116
+ case response.headers['Content-Type']
117
+ when 'audio/mpeg', 'application/x-shockwave-flash'
118
+ return response_body
119
+ else
120
+ raise RequestError.from_url(url, response_body)
121
+ end
122
+ rescue Faraday::Error::ConnectionFailed => err
123
+ raise RequestError.from_url(url, err.message)
124
+ end
125
+ private :send_request
126
+
127
+ # Ensure all required attributes are present.
128
+ #
129
+ # @return [void]
130
+ def validate!
131
+ raise(Error, 'secret_phrase is missing') unless secret_phrase
132
+ raise(Error, 'api_id is missing') unless api_id
133
+ raise(Error, 'account_id is missing') unless account_id
134
+ raise(Error, 'voice is missing') unless voice
135
+
136
+ raise(Error,
137
+ 'voice must be a Vocalware::Voice'
138
+ ) unless voice.is_a?(Voice)
139
+ end
140
+ private :validate!
141
+
142
+ # Represent all client attributes as a hash.
143
+ #
144
+ # @return [Hash<Symbol, Object>]
145
+ def to_hash
146
+ { :host => host,
147
+ :path => path,
148
+ :protocol => protocol,
149
+ :port => port,
150
+ :account_id => account_id,
151
+ :api_id => api_id,
152
+ :secret_phrase => secret_phrase,
153
+ :voice => voice,
154
+ :ext => ext }
155
+ end
156
+ private :to_hash
157
+ end
158
+ end
@@ -0,0 +1,40 @@
1
+ module Vocalware
2
+ # Basic Vocalware error.
3
+ class Error < StandardError
4
+ end
5
+
6
+ # Raised when no voices or more than one are found.
7
+ class FindVoiceError < Error
8
+ end
9
+
10
+ # Raised on sending and processing HTTP request to Vocalware service.
11
+ class RequestError < Error
12
+ # @attribute url [String] URL where request was sent
13
+ attr_accessor :url
14
+
15
+ # @attribute response [Faraday::Response] recevied response
16
+ attr_accessor :response
17
+
18
+ # Create instance with request URL and error message.
19
+ #
20
+ # @return [Vocalware::RequestError]
21
+ def self.from_url(url, message)
22
+ message << "\nREQUEST URL: #{url}"
23
+ new(message)
24
+ end
25
+
26
+ # Create instance with request URL, response and error message.
27
+ #
28
+ # @return [Vocalware::RequestError]
29
+ def self.from_url_and_response(url, response, message)
30
+ message << "\nREQUEST URL: #{url}"
31
+ message << "\nRESPONSE STATUS: #{response.status}"
32
+ message << "\nRESPONSE BODY: #{response.body}"
33
+ new(message)
34
+ end
35
+ end
36
+
37
+ # Raised when required parameters for request are missing.
38
+ class BuildRequestError < RequestError
39
+ end
40
+ end
@@ -0,0 +1,73 @@
1
+ module Vocalware
2
+ # Maps language ISO 639-1 code to Vocalware language id.
3
+ LANGUAGES = {
4
+ # Arabic
5
+ :ar => 27,
6
+
7
+ # Catalan
8
+ :ca => 5,
9
+
10
+ # Chinese
11
+ :zh => 10,
12
+
13
+ # Danish
14
+ :da => 19,
15
+
16
+ # Dutch
17
+ :nl => 11,
18
+
19
+ # English
20
+ :en => 1,
21
+
22
+ # Esperanto
23
+ :eo => 31,
24
+
25
+ # Finnish
26
+ :fi => 23,
27
+
28
+ # French
29
+ :fr => 4,
30
+
31
+ # Galician
32
+ :gl => 15,
33
+
34
+ # German
35
+ :de => 3,
36
+
37
+ # Greek
38
+ :el => 8,
39
+
40
+ # Italian
41
+ :it => 7,
42
+
43
+ # Japanese
44
+ :ja => 12,
45
+
46
+ # Korean
47
+ :ko => 13,
48
+
49
+ # Norwegian
50
+ :no => 20,
51
+
52
+ # Polish
53
+ :pl => 14,
54
+
55
+ # Portuguese
56
+ :pt => 6,
57
+
58
+ # Romanian
59
+ :ro => 30,
60
+
61
+ # Russian
62
+ :ru => 21,
63
+
64
+ # Spanish
65
+ :es => 2,
66
+
67
+ # Swedish
68
+ :sv => 9,
69
+
70
+ # Turkish
71
+ :tr => 16
72
+ }.freeze
73
+ end
@@ -0,0 +1,88 @@
1
+ module Vocalware
2
+ # Request to send to Vocalware's remote service.
3
+ # Builds a URL with all necessary parameters according to the API.
4
+ class Request
5
+ # Required parameters according to the Vocalware API reference.
6
+ REQUIRED_PARAMETERS = ['EID', 'LID', 'VID', 'TXT', 'ACC', 'API', 'CS']
7
+
8
+ # @param attrs [Hash<Symbol, Object>]
9
+ def initialize(attrs)
10
+ @attrs = attrs
11
+ validate!
12
+ end
13
+
14
+ # Build a query as a URL with GET parameters.
15
+ #
16
+ # @return [String]
17
+ def to_url
18
+ port = @attrs[:port]
19
+ url = "#{@attrs[:protocol]}://#{@attrs[:host]}"
20
+ url << ":#{port}" if port
21
+ url << "#{@attrs[:path]}?"
22
+
23
+ params_str = params.map {|name, value|
24
+ "#{CGI.escape(name)}=#{CGI.escape(value)}"
25
+ }.join('&')
26
+ url << params_str
27
+ end
28
+
29
+ # Validate all required parameters are present.
30
+ #
31
+ # @return [void]
32
+ def validate!
33
+ REQUIRED_PARAMETERS.each do |name|
34
+ if params[name].empty?
35
+ raise(BuildRequestError, "Vocalware: Parameter #{name} is required")
36
+ end
37
+ end
38
+ end
39
+ private :validate!
40
+
41
+ # Build GET parameters.
42
+ #
43
+ # @return [Hash<String, String>]
44
+ def params
45
+ @params ||= begin
46
+ voice = @attrs[:voice]
47
+ { 'EID' => voice.engine_id.to_s,
48
+ 'LID' => voice.lang_id.to_s,
49
+ 'VID' => voice.voice_id.to_s,
50
+ 'TXT' => @attrs[:text].to_s,
51
+ 'EXT' => @attrs[:ext].to_s,
52
+ 'FX_TYPE' => @attrs[:fx_type].to_s,
53
+ 'FX_LEVEL' => @attrs[:fx_level].to_s,
54
+ 'ACC' => @attrs[:account_id].to_s,
55
+ 'API' => @attrs[:api_id].to_s,
56
+ 'SESSION' => @attrs[:session].to_s,
57
+ 'CS' => checksum }
58
+ end
59
+ end
60
+ private :params
61
+
62
+ # Calculate checksum. The following formula is used:
63
+ # CS = md5(EID + LID + VID + TXT + EXT + FX_TYPE + FX_LEVEL +
64
+ # + fACC + API + SESSION + SECRET PHRASE)
65
+ #
66
+ # @return [String] MD5 hex digest
67
+ def checksum
68
+ @checksum ||= begin
69
+ voice = @attrs[:voice]
70
+ data = [
71
+ voice.engine_id.to_s,
72
+ voice.lang_id.to_s,
73
+ voice.voice_id.to_s,
74
+ @attrs[:text].to_s,
75
+ @attrs[:ext].to_s,
76
+ @attrs[:fx_type].to_s,
77
+ @attrs[:fx_level].to_s,
78
+ @attrs[:account_id].to_s,
79
+ @attrs[:api_id].to_s,
80
+ @attrs[:session].to_s,
81
+ @attrs[:secret_phrase].to_s
82
+ ].join('')
83
+ Digest::MD5.hexdigest(data)
84
+ end
85
+ end
86
+ private :checksum
87
+ end
88
+ end
@@ -0,0 +1,94 @@
1
+ module Vocalware
2
+ # Voice encapsulates voice parameters like +engine_id+, +voice_id+, +lang_id+
3
+ # etc. And provides class method to look up voice by parameters.
4
+ #
5
+ # @example
6
+ # # Find a voice with name Juan. Exception will be raise if the voice with
7
+ # # such name is not unique. As well as if the voice not found.
8
+ # voice = Voice.find(:name => 'Juan')
9
+ class Voice
10
+ # @attr_reader engine_id [Integer, String] engine id which is used to
11
+ # generate speech
12
+ attr_reader :engine_id
13
+
14
+ # @attr_reader lang [Symbol, String] language ISO 639-1 code (2 chars)
15
+ attr_reader :lang
16
+
17
+ # @attr_reader name [String] voice name
18
+ attr_reader :name
19
+
20
+ # @attr_reader voice_id [Integer, String] unique only in scope of
21
+ # +engine_id+ and +lang+
22
+ attr_reader :voice_id
23
+
24
+ # @attr_reader gender [String] whether "M" or "F"
25
+ attr_reader :gender
26
+
27
+ # @attr_reader description [String] regions, dialects, etc
28
+ attr_reader :description
29
+
30
+ # @attr_reader lang_id [Integer, String] language id
31
+ attr_reader :lang_id
32
+
33
+ # Get all voices.
34
+ #
35
+ # @return [Array<Vocalware::Voice>]
36
+ def self.all
37
+ @all ||= send(:load_all)
38
+ end
39
+
40
+ # Find a voice by attributes.
41
+ #
42
+ # @param attrs [Hash] attributes to find a voice
43
+ #
44
+ # @return
45
+ def self.find(attrs)
46
+ voices = all.select {|voice| voice.match?(attrs) }
47
+
48
+ raise(FindVoiceError,
49
+ "No voice found using #{attrs.inspect}"
50
+ ) if voices.empty?
51
+ raise(FindVoiceError,
52
+ "More than 1 voice found using #{attrs.inspect}"
53
+ ) if voices.size > 1
54
+
55
+ voices.first
56
+ end
57
+
58
+ # Load and instantiate voices from CSV file.
59
+ #
60
+ # @return [Array<Vocalware::Voice>]
61
+ def self.load_all
62
+ converter = lambda { |str| str ? str.strip! : nil }
63
+ data = CSV.read( VOICES_CSV_FILE,
64
+ :headers => true,
65
+ :skip_blanks => true,
66
+ :converters => converter,
67
+ :header_converters => converter )
68
+ data.map { |row| Voice.new(row.to_hash) }
69
+ end
70
+ private_class_method :load_all
71
+
72
+
73
+ # @param attributes [Hash] voice attributes
74
+ def initialize(attributes)
75
+ attributes.each do |attr, value|
76
+ self.instance_variable_set("@#{attr}", value)
77
+ end
78
+ @lang_id = LANGUAGES[lang.to_sym] ||
79
+ raise(Error, "Unknown lang #{lang.inspect}")
80
+ end
81
+
82
+ # Verify that the voice matches the passed attributes.
83
+ #
84
+ # @param attributes [Hash]
85
+ #
86
+ # @return [Boolean]
87
+ def match?(attributes)
88
+ attributes.each do |attr, val|
89
+ return false if send(attr).to_s != val.to_s
90
+ end
91
+ true
92
+ end
93
+ end
94
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vocalware
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - TMX Credit
8
+ - Potapov Sergey
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: faraday
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '1.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '1.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: jeweler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: 1.8.7
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 1.8.7
56
+ - !ruby/object:Gem::Dependency
57
+ name: yard
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: metric_fu
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: pry
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: pry-nav
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ description: Ruby client for Vocalware REST API
113
+ email:
114
+ - rubygems@tmxcredit.com
115
+ - blake131313@gmail.com
116
+ executables: []
117
+ extensions: []
118
+ extra_rdoc_files:
119
+ - LICENSE.txt
120
+ - README.markdown
121
+ files:
122
+ - LICENSE.txt
123
+ - README.markdown
124
+ - data/voices.csv
125
+ - lib/vocalware.rb
126
+ - lib/vocalware/client.rb
127
+ - lib/vocalware/errors.rb
128
+ - lib/vocalware/languages.rb
129
+ - lib/vocalware/request.rb
130
+ - lib/vocalware/voice.rb
131
+ homepage: http://github.com/TMXCredit/vocalware
132
+ licenses:
133
+ - MIT
134
+ metadata: {}
135
+ post_install_message:
136
+ rdoc_options: []
137
+ require_paths:
138
+ - lib
139
+ required_ruby_version: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ required_rubygems_version: !ruby/object:Gem::Requirement
145
+ requirements:
146
+ - - '>='
147
+ - !ruby/object:Gem::Version
148
+ version: '0'
149
+ requirements: []
150
+ rubyforge_project:
151
+ rubygems_version: 2.0.3
152
+ signing_key:
153
+ specification_version: 4
154
+ summary: Ruby client for Vocalware REST API
155
+ test_files: []
156
+ has_rdoc: