verbalizeit 1.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 +7 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +150 -0
- data/Rakefile +2 -0
- data/lib/verbalizeit.rb +10 -0
- data/lib/verbalizeit/client.rb +151 -0
- data/lib/verbalizeit/error.rb +21 -0
- data/lib/verbalizeit/language.rb +16 -0
- data/lib/verbalizeit/task.rb +110 -0
- data/lib/verbalizeit/translator.rb +17 -0
- data/lib/verbalizeit/version.rb +3 -0
- data/spec/fixtures/cassettes/client/completed_file.yml +224 -0
- data/spec/fixtures/cassettes/client/completed_file_not_found.yml +186 -0
- data/spec/fixtures/cassettes/client/create_postback_task.yml +188 -0
- data/spec/fixtures/cassettes/client/create_task.yml +188 -0
- data/spec/fixtures/cassettes/client/create_task_start_task.yml +188 -0
- data/spec/fixtures/cassettes/client/get_task.yml +188 -0
- data/spec/fixtures/cassettes/client/get_task_not_found.yml +186 -0
- data/spec/fixtures/cassettes/client/language_list.yml +132 -0
- data/spec/fixtures/cassettes/client/list_tasks.yml +188 -0
- data/spec/fixtures/cassettes/client/list_tasks_start_limit.yml +188 -0
- data/spec/fixtures/cassettes/client/list_tasks_status.yml +188 -0
- data/spec/fixtures/cassettes/client/no_file_or_url.yml +186 -0
- data/spec/fixtures/cassettes/client/no_operation.yml +186 -0
- data/spec/fixtures/cassettes/client/no_source_language.yml +186 -0
- data/spec/fixtures/cassettes/client/no_target_language.yml +186 -0
- data/spec/fixtures/cassettes/client/start_task.yml +244 -0
- data/spec/fixtures/cassettes/client/start_task_forbidden.yml +57 -0
- data/spec/fixtures/cassettes/client/start_task_not_found.yml +186 -0
- data/spec/fixtures/cassettes/client/unauthorized.yml +54 -0
- data/spec/fixtures/cassettes/language/find_by_language_region_code.yml +132 -0
- data/spec/fixtures/cassettes/task/languages.yml +132 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/created_task.json +32 -0
- data/spec/support/sample.srt +39 -0
- data/spec/support/sample.xliff +21 -0
- data/spec/verbalizeit/client_spec.rb +326 -0
- data/spec/verbalizeit/language_spec.rb +50 -0
- data/spec/verbalizeit/task_spec.rb +124 -0
- data/spec/verbalizeit/translator_spec.rb +21 -0
- data/verbalizeit.gemspec +29 -0
- metadata +228 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 96a46207cd03946e6882b755dda04b6d7cacc70f
|
4
|
+
data.tar.gz: 6e21afa7e84b5928c542e1e024c31a5c298a3856
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ad3107664c67a828e43bb800f3b0d9a3d365d91fafbbf38530d4a2d73984aca3b7b197a47a2f32ab1a13e2cf9b420f1b169be40073c77dd5606fa160a69e2aa7
|
7
|
+
data.tar.gz: ab7be31b5b3de30e2e5d0cd5418baaa44fb4e9737c119d44e96cab1748bac214f13ccd5a83f703a110a80efc428553f6dfac71f9b47c7bdff61abf0961e55e6f
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
.env
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Nathanael Burt
|
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,150 @@
|
|
1
|
+
# Verbalizeit
|
2
|
+
|
3
|
+
The VerbalizeIt gem is a wrapper for [VerbalizeIt’s](https://www.verbalizeit.com) V2 API. Full documentation for the V2 API can be found [here](https://customers.verbalizeit.com/api_documentation). The VerbalizeIt API allows developers to submit files for translation or transcription directly, without using the Customer Dashboard.
|
4
|
+
|
5
|
+
## Code Status
|
6
|
+
|
7
|
+
[](https://circleci.com/gh/VerbalizeItInc/verbalizeit)
|
8
|
+
[](https://codeclimate.com/github/VerbalizeItInc/verbalizeit)
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
gem 'verbalizeit'
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
$ bundle
|
19
|
+
|
20
|
+
Or install it yourself as:
|
21
|
+
|
22
|
+
$ gem install verbalizeit
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
The VerbalizeIt gem supports the same endpoints as the V2 API.
|
27
|
+
|
28
|
+
### Authentication
|
29
|
+
|
30
|
+
Initialize the VerbalizeIt client with your API key and the API environment. The supported API environments are `:staging` and `:production`.
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
client = VerbalizeIt::Client.new('my_key', :staging)
|
34
|
+
```
|
35
|
+
|
36
|
+
### Languages
|
37
|
+
|
38
|
+
##### List
|
39
|
+
|
40
|
+
Returns an array of `Verbalizeit::Language` objects.
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
languages = client.languages
|
44
|
+
#=> [Verbalizeit::Language,...]
|
45
|
+
```
|
46
|
+
|
47
|
+
A `Verbalizeit::Language` has a `name` and a `language_region_code`
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
language = languages.first
|
51
|
+
|
52
|
+
language.name
|
53
|
+
#=> "English"
|
54
|
+
language.language_region_code
|
55
|
+
#=> "eng-US"
|
56
|
+
```
|
57
|
+
|
58
|
+
### Tasks
|
59
|
+
|
60
|
+
##### List
|
61
|
+
|
62
|
+
Returns an array of `Verbalizeit::Task` objects. `list_tasks` has three optional parameters: `start`, `limit`, and `status`. By default, the `limit` is set to 10.
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
client.list_tasks({start: 0, limit: 5, status: 'preview'})
|
66
|
+
#=> {
|
67
|
+
# total: 10,
|
68
|
+
# start: 0,
|
69
|
+
# limit: 5,
|
70
|
+
# tasks: [Verbalizeit::Task,...]
|
71
|
+
# }
|
72
|
+
```
|
73
|
+
|
74
|
+
##### Show
|
75
|
+
|
76
|
+
Returns a `Verbalizeit::Task` object.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
id = 'T2EB60C'
|
80
|
+
task = client.get_task(id)
|
81
|
+
#=> Verbalizeit::Task
|
82
|
+
```
|
83
|
+
|
84
|
+
A task has methods for each attribute. See the [tasks show response](https://customers.verbalizeit.com/api_documentation#tasks_show) in the V2 API documentation for a full list of attributes.
|
85
|
+
|
86
|
+
```ruby
|
87
|
+
task.id
|
88
|
+
#=> 'T2EB60C'
|
89
|
+
|
90
|
+
task.status
|
91
|
+
#=> 'preview'
|
92
|
+
|
93
|
+
task.price_amount
|
94
|
+
#=> 11.22
|
95
|
+
```
|
96
|
+
|
97
|
+
##### Create
|
98
|
+
|
99
|
+
Creates a new task in the VerbalizeIt system. Returns a `Verbalizeit::Task`.
|
100
|
+
|
101
|
+
Required parameters: `operation`, `source_language`, `target_language`, at least one of `file` or `media_resource_url`.
|
102
|
+
Optional parameters: `postback_url`, `status_url`, `start`, `rush_order`
|
103
|
+
|
104
|
+
Optional parameters, as well as the `file` and `media_resource_url`, are passed in through an options hash.
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
client.create_task('text_translation', 'eng-US', 'fra-FR', {file: 'file.xliff', postback_url: 'https://www.postback.com'})
|
108
|
+
#=> Verbalizeit::Task
|
109
|
+
```
|
110
|
+
|
111
|
+
##### Start
|
112
|
+
|
113
|
+
Starts a created task. Returns a status code of `200`.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
id = 'T2EB60C'
|
117
|
+
client.start_task(id)
|
118
|
+
#=> 200
|
119
|
+
```
|
120
|
+
|
121
|
+
##### Download Completed File
|
122
|
+
|
123
|
+
Returns a struct with the filename and body of a completed file for a task. Only available if the task is in the "complete" state.
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
id = 'T2EB60C'
|
127
|
+
completed_file = client.task_completed_file(id)
|
128
|
+
completed_file.filename
|
129
|
+
#=> sample.txt
|
130
|
+
completed_file.content
|
131
|
+
#=> "This is some sample text. \n\n And here is another paragraph"
|
132
|
+
```
|
133
|
+
|
134
|
+
If you would like to write the file to your local filesytem, you could do something like this.
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
file = File.open(completed_file.filename, "w")
|
138
|
+
file << completed_file.content
|
139
|
+
file.close
|
140
|
+
```
|
141
|
+
|
142
|
+
### Errors
|
143
|
+
|
144
|
+
There are 5 types of errors.
|
145
|
+
|
146
|
+
* `Verbalizeit::Error::Unauthorized` is raised if the `Verbalizeit::Client` is initialized with an invalid API key, or if the API key does not match the environement. API keys can be created from the customer dashboard under 'API' in the left-hand navigation.
|
147
|
+
* `Verbalizeit::Error::UnknownEnvironment` is raised if the client is initialized with an environment that does not exist. The available environments are `:staging` and `:production`.
|
148
|
+
* `Verbalizeit::Error::BadRequest` can be raised for a variety of reasons, the error message will help you debug why this is being raised. Common examples would be creating a task with an invalid `operation`, `source_language`, or `target_language`.
|
149
|
+
* `Verbalizeit::Error::Forbidden` is raised if the user tries to access a task that does not belong to them.
|
150
|
+
* `Verbalizeit::Error::NotFound` is raised if the user tries to access a task that does not exist.
|
data/Rakefile
ADDED
data/lib/verbalizeit.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'json'
|
3
|
+
module Verbalizeit
|
4
|
+
class Client
|
5
|
+
|
6
|
+
attr_reader :languages
|
7
|
+
|
8
|
+
def initialize(api_key, environement)
|
9
|
+
@api_key = api_key
|
10
|
+
@environment = environement
|
11
|
+
@languages = fetch_languages
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_task(source_language, target_language, operation, options = {})
|
15
|
+
body = {
|
16
|
+
source_language: source_language,
|
17
|
+
target_language: target_language,
|
18
|
+
operation: operation,
|
19
|
+
file: options[:file],
|
20
|
+
media_resource_url: options[:media_resource_url],
|
21
|
+
start: "#{options[:start]}",
|
22
|
+
rush_order: "#{options[:rush_order]}",
|
23
|
+
postback_url: options[:postback_url],
|
24
|
+
status_url: options[:status_url]
|
25
|
+
}
|
26
|
+
|
27
|
+
response = Typhoeus.post(tasks_url, body: body, headers: authorization_header)
|
28
|
+
|
29
|
+
if response.code == 200
|
30
|
+
Task.from(parse_body(response.body), self)
|
31
|
+
elsif response.code == 400
|
32
|
+
raise Error::BadRequest, format_errors(response.body)
|
33
|
+
elsif response.code == 401
|
34
|
+
raise Error::Unauthorized
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def list_tasks(options = {})
|
39
|
+
params = {
|
40
|
+
start: options[:start],
|
41
|
+
limit: options[:limit] || 10,
|
42
|
+
status: options[:status]
|
43
|
+
}
|
44
|
+
response = Typhoeus.get(tasks_url, params: params, headers: authorization_header)
|
45
|
+
|
46
|
+
if response.code == 200
|
47
|
+
list_tasks_success(response.body)
|
48
|
+
else
|
49
|
+
raise Error::NotImplemented
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_task(id)
|
54
|
+
response = Typhoeus.get(get_task_url(id), headers: authorization_header)
|
55
|
+
validate_response(response.code)
|
56
|
+
Task.from(parse_body(response.body), self)
|
57
|
+
end
|
58
|
+
|
59
|
+
def start_task(id)
|
60
|
+
response = Typhoeus.post(start_task_url(id), headers: authorization_header)
|
61
|
+
validate_response(response.code)
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
def task_completed_file(id)
|
66
|
+
response = Typhoeus.get(task_completed_file_url(id), headers: authorization_header)
|
67
|
+
validate_response(response.code)
|
68
|
+
|
69
|
+
# original string => "attachment; filename=\"sample.srt\""
|
70
|
+
filename = response.headers["Content-Disposition"].rpartition("filename=").last
|
71
|
+
struct = Struct.new(:filename, :content)
|
72
|
+
struct.new(filename, response.body)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def validate_response(code)
|
78
|
+
if code == 404
|
79
|
+
raise Error::NotFound
|
80
|
+
elsif code == 403
|
81
|
+
raise Error::Forbidden
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def list_tasks_success(body)
|
86
|
+
parsed_body = parse_body(body)
|
87
|
+
|
88
|
+
{
|
89
|
+
total: parsed_body["total"],
|
90
|
+
start: parsed_body["start"],
|
91
|
+
limit: parsed_body["limit"],
|
92
|
+
tasks: parsed_body["tasks"].map { |task| Task.from(task, self) }
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def fetch_languages
|
97
|
+
response = Typhoeus.get(languages_url, headers: authorization_header)
|
98
|
+
|
99
|
+
if response.code == 200
|
100
|
+
parsed_body = JSON.parse(response.body)
|
101
|
+
parsed_body.map { |language| Language.new(language) }
|
102
|
+
elsif response.code == 401
|
103
|
+
raise Error::Unauthorized
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def task_completed_file_url(id)
|
108
|
+
get_task_url(id) << "/completed_file"
|
109
|
+
end
|
110
|
+
|
111
|
+
def start_task_url(id)
|
112
|
+
get_task_url(id) << "/start"
|
113
|
+
end
|
114
|
+
|
115
|
+
def get_task_url(id)
|
116
|
+
tasks_url << "/#{id}"
|
117
|
+
end
|
118
|
+
|
119
|
+
def tasks_url
|
120
|
+
base_url << "tasks"
|
121
|
+
end
|
122
|
+
|
123
|
+
def languages_url
|
124
|
+
base_url << "languages"
|
125
|
+
end
|
126
|
+
|
127
|
+
def base_url
|
128
|
+
case @environment
|
129
|
+
when :staging
|
130
|
+
"https://stagingapi.verbalizeit.com/v2/"
|
131
|
+
when :production
|
132
|
+
"https://api.verbalizeit.com/v2/"
|
133
|
+
else
|
134
|
+
raise Error::UnknownEnvironment, "you may specify :staging or :production"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def authorization_header
|
139
|
+
{"x-api-key" => @api_key}
|
140
|
+
end
|
141
|
+
|
142
|
+
def format_errors(body)
|
143
|
+
parse_body(body).map { |_, errors| errors.map { |type, error| error } }.flatten.join(".")
|
144
|
+
end
|
145
|
+
|
146
|
+
def parse_body(body)
|
147
|
+
JSON.parse(body)
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Verbalizeit
|
2
|
+
module Error
|
3
|
+
class UnknownEnvironment < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class Unauthorized < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
class BadRequest < StandardError
|
10
|
+
end
|
11
|
+
|
12
|
+
class NotImplemented < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
class Forbidden < StandardError
|
16
|
+
end
|
17
|
+
|
18
|
+
class NotFound < StandardError
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Verbalizeit
|
2
|
+
class Language
|
3
|
+
|
4
|
+
attr_reader :name, :language_region_code
|
5
|
+
|
6
|
+
def initialize(attributes)
|
7
|
+
@name = attributes[:name] || attributes["name"]
|
8
|
+
@language_region_code = attributes[:language_region_code] || attributes["language_region_code"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.find_by_language_region_code(languages, language_region_code)
|
12
|
+
languages.select {|l| l.language_region_code == language_region_code}.first
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Verbalizeit
|
2
|
+
class Task
|
3
|
+
|
4
|
+
def self.from(body, client)
|
5
|
+
new(body, client)
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(task, client)
|
9
|
+
@task = task
|
10
|
+
@client = client
|
11
|
+
end
|
12
|
+
|
13
|
+
def id
|
14
|
+
@task["id"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def url
|
18
|
+
@task["url"]
|
19
|
+
end
|
20
|
+
|
21
|
+
def status
|
22
|
+
@task["status"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def rush_order
|
26
|
+
@task["rush_order"]
|
27
|
+
end
|
28
|
+
|
29
|
+
def project_name
|
30
|
+
@task["project_name"]
|
31
|
+
end
|
32
|
+
|
33
|
+
def source_language
|
34
|
+
Language.find_by_language_region_code(@client.languages, @task["source_language"])
|
35
|
+
end
|
36
|
+
|
37
|
+
def target_language
|
38
|
+
Language.find_by_language_region_code(@client.languages, @task["target_language"])
|
39
|
+
end
|
40
|
+
|
41
|
+
def price_currency
|
42
|
+
@task["price_currency"]
|
43
|
+
end
|
44
|
+
|
45
|
+
def price_amount
|
46
|
+
@task["price_amount"]
|
47
|
+
end
|
48
|
+
|
49
|
+
def due_at
|
50
|
+
@task["due_at"]
|
51
|
+
end
|
52
|
+
|
53
|
+
def completed_at
|
54
|
+
@task["completed_at"]
|
55
|
+
end
|
56
|
+
|
57
|
+
def created_at
|
58
|
+
@task["created_at"]
|
59
|
+
end
|
60
|
+
|
61
|
+
def operation
|
62
|
+
@task["operation"]
|
63
|
+
end
|
64
|
+
|
65
|
+
def download_url
|
66
|
+
@task["download_url"]
|
67
|
+
end
|
68
|
+
|
69
|
+
def source_download_url
|
70
|
+
@task["source_download_url"]
|
71
|
+
end
|
72
|
+
|
73
|
+
def source_filename
|
74
|
+
@task["source_filename"]
|
75
|
+
end
|
76
|
+
|
77
|
+
def unit_count
|
78
|
+
@task["unit_count"]
|
79
|
+
end
|
80
|
+
|
81
|
+
def unit_type
|
82
|
+
@task["unit_type"]
|
83
|
+
end
|
84
|
+
|
85
|
+
def translation_units
|
86
|
+
@task["translation_units"]
|
87
|
+
end
|
88
|
+
|
89
|
+
def translation_units_complete
|
90
|
+
@task["translation_units_complete"]
|
91
|
+
end
|
92
|
+
|
93
|
+
def translator
|
94
|
+
Translator.new(@task["translator"])
|
95
|
+
end
|
96
|
+
|
97
|
+
def reviewer
|
98
|
+
Translator.new(@task["reviewer"])
|
99
|
+
end
|
100
|
+
|
101
|
+
def postback_url
|
102
|
+
@task["postback_url"]
|
103
|
+
end
|
104
|
+
|
105
|
+
def status_url
|
106
|
+
@task["status_url"]
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|