abbyy-cloud 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +24 -0
- data/README.md +60 -33
- data/abbyy-cloud.gemspec +1 -1
- data/lib/abbyy/cloud.rb +10 -16
- data/lib/abbyy/cloud/connection.rb +31 -17
- data/lib/abbyy/cloud/models/direction.rb +4 -2
- data/lib/abbyy/cloud/models/discount.rb +12 -0
- data/lib/abbyy/cloud/models/engine.rb +4 -1
- data/lib/abbyy/cloud/models/locale.rb +23 -0
- data/lib/abbyy/cloud/models/price.rb +22 -0
- data/lib/abbyy/cloud/models/source_segment.rb +14 -0
- data/lib/abbyy/cloud/models/source_tag.rb +15 -0
- data/lib/abbyy/cloud/models/transfer_data.rb +14 -0
- data/lib/abbyy/cloud/models/translation.rb +1 -1
- data/lib/abbyy/cloud/models/translation_segment.rb +16 -0
- data/lib/abbyy/cloud/models/unit_price.rb +13 -0
- data/lib/abbyy/cloud/namespaces/machine_translations.rb +47 -1
- data/lib/abbyy/cloud/namespaces/prices.rb +29 -0
- data/lib/abbyy/cloud/operations/base.rb +20 -6
- data/lib/abbyy/cloud/operations/engines.rb +3 -1
- data/lib/abbyy/cloud/operations/prices.rb +23 -0
- data/lib/abbyy/cloud/operations/translate.rb +5 -3
- data/lib/abbyy/cloud/operations/translate_segments.rb +22 -0
- data/lib/abbyy/cloud/settings.rb +4 -5
- data/lib/abbyy/cloud/types.rb +14 -10
- data/spec/abbyy/cloud/connection_spec.rb +1 -1
- data/spec/abbyy/cloud/models/discount_spec.rb +32 -0
- data/spec/abbyy/cloud/models/locale_spec.rb +55 -0
- data/spec/abbyy/cloud/models/price_spec.rb +107 -0
- data/spec/abbyy/cloud/models/source_segment_spec.rb +37 -0
- data/spec/abbyy/cloud/models/source_tag_spec.rb +56 -0
- data/spec/abbyy/cloud/models/transfer_data_spec.rb +40 -0
- data/spec/abbyy/cloud/models/translation_segment_spec.rb +38 -0
- data/spec/abbyy/cloud/models/unit_price_spec.rb +48 -0
- data/spec/abbyy/cloud/settings_spec.rb +2 -24
- data/spec/abbyy/cloud_spec.rb +3 -4
- data/spec/feature/abbyy/mt_default_engine_spec.rb +12 -0
- data/spec/feature/abbyy/mt_engine_spec.rb +15 -0
- data/spec/feature/abbyy/mt_translate_segments_spec.rb +136 -0
- data/spec/feature/abbyy/{order_translate_spec.rb → mt_translate_spec.rb} +2 -2
- data/spec/feature/abbyy/prices_details_spec.rb +70 -0
- metadata +39 -5
- data/lib/abbyy/cloud/namespaces/orders.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86781ecddc4c6d75b7eca75244bb940bf82c0df1
|
4
|
+
data.tar.gz: 4fbafddffeab9bbbbc23d8e951e7f04bf5ece6c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46fdfc138c2b78f7e555ee80dc19c2b971cf12768e10569ee6eda8c6529030e9401d6d35ab50dc08266862b60af5e70f4a725bd6ff9df00c7caea2ff4cb355e0
|
7
|
+
data.tar.gz: ca541399867b4f463ce81f261f2e189afff31b218a7d8532008a78bbc9849ddd6f2d7b10c111396fb4b43245acb88d62b963ba3b8b3d698b3b900f816a6cefed
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
# [v0.0.4 2016-08-23](https://github.com/nepalez/abbyy-cloud/tree/v0.0.4)
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
* Operation `mt.engine(name)` (nepalez)
|
6
|
+
* Operation `mt.default_engine` (nepalez)
|
7
|
+
* Operation `mt.translate` instead of `orders.translate` (nepalez)
|
8
|
+
* Operation `mt.translate_segments` (nepalez)
|
9
|
+
* Operation `prices.details` (nepalez)
|
10
|
+
* Validation of locales following IANA & RFC-5646 (nepalez)
|
11
|
+
|
12
|
+
### Deleted
|
13
|
+
|
14
|
+
* Namespace `orders` (nepalez)
|
15
|
+
* Remove :version settings (nepalez)
|
16
|
+
Every operation has its own version. No global API version is supported.
|
17
|
+
When necessary, a version will be send to the operation.
|
18
|
+
|
19
|
+
### Internal
|
20
|
+
|
21
|
+
* Added support for query part of a request (nepalez)
|
22
|
+
|
23
|
+
[Compare v0.0.3...v0.0.4](https://github.com/nepalez/abbyy-cloud/compare/v0.0.3...v0.0.4)
|
24
|
+
|
1
25
|
# [v0.0.3 2016-08-18](https://github.com/nepalez/abbyy-cloud/tree/v0.0.3)
|
2
26
|
|
3
27
|
### Bugs Fixed
|
data/README.md
CHANGED
@@ -22,20 +22,31 @@ require "abbyy/cloud"
|
|
22
22
|
CLIENT = ABBYY::Cloud.new(id: "foo", token: "bar")
|
23
23
|
```
|
24
24
|
|
25
|
-
The only supported API version is `0`. By default the translation engine is set to "Sandbox".
|
26
|
-
|
27
25
|
You can set these options explicitly:
|
28
26
|
|
29
27
|
```ruby
|
30
28
|
CLIENT = ABBYY::Cloud.new id: "foo",
|
31
29
|
token: "bar",
|
32
|
-
engine: "Sandbox"
|
33
|
-
|
30
|
+
engine: "Sandbox" # default engine for translations
|
31
|
+
```
|
32
|
+
|
33
|
+
And then use the client to provide requests:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
res = CLIENT.mt.translate("To be or not to be", from: :en, to: :ru)
|
37
|
+
res.translation # => "Быть или не быть"
|
38
|
+
|
39
|
+
res = CLIENT.mt.translate_segments ["To be or not to be", "That is the question"], from: "en", to: "ru"
|
40
|
+
res.map(&:text) # => ["Быть или не быть", "Это вопрос"]
|
34
41
|
```
|
35
42
|
|
43
|
+
## Namespaces and Operations
|
44
|
+
|
36
45
|
### Machine Translations
|
37
46
|
|
38
|
-
|
47
|
+
The namespace `mt` contains (synchronous) operations with machine translation.
|
48
|
+
|
49
|
+
#### engines
|
39
50
|
|
40
51
|
See [the specification](https://api.abbyy.cloud/swagger/ui/index#!/MachineTranslation)
|
41
52
|
|
@@ -44,7 +55,7 @@ result = CLIENT.mt.engines
|
|
44
55
|
# => [#<ABBYY::Cloud::Models::Engine @name="Sandbox">]
|
45
56
|
```
|
46
57
|
|
47
|
-
####
|
58
|
+
#### engine
|
48
59
|
|
49
60
|
This operation is built on top of the previous one and simply takes settings for the specified engine:
|
50
61
|
|
@@ -59,14 +70,24 @@ result.to_h
|
|
59
70
|
# => { name: "Sandbox", languages: ["en", "ru"], translation_directions: [{ source: "en", target: "ru" }] }
|
60
71
|
```
|
61
72
|
|
62
|
-
|
73
|
+
#### default_engine
|
74
|
+
|
75
|
+
Returns settings for the engine used in the initializer
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
CLIENT = ABBYY::Cloud.new(id: "foo", token: "bar", engine: "Bing")
|
79
|
+
|
80
|
+
settings_for_bing = CLIENT.mt.default_engine
|
81
|
+
```
|
82
|
+
|
83
|
+
#### translate
|
63
84
|
|
64
|
-
|
85
|
+
Translates a string.
|
65
86
|
|
66
87
|
See [the specification](https://api.abbyy.cloud/swagger/ui/index#!/Order/Order_Translate).
|
67
88
|
|
68
89
|
```ruby
|
69
|
-
result = CLIENT.
|
90
|
+
result = CLIENT.mt.translate("To be or not to be", from: :en, to: :ru)
|
70
91
|
|
71
92
|
result.class # => ABBYY::Cloud::Models::Translation
|
72
93
|
result.translation # => "Быть или не быть"
|
@@ -74,42 +95,48 @@ result.id # => "2832934"
|
|
74
95
|
result.to_h # => { id: "2832934", translation: "Быть или не быть" }
|
75
96
|
```
|
76
97
|
|
77
|
-
|
98
|
+
#### translate_segments
|
78
99
|
|
79
|
-
|
80
|
-
CLIENT.orders.translate("To be or not to be", from: :en, to: :ru, engine: "Bing")
|
81
|
-
```
|
100
|
+
Translates an array of strings in one request
|
82
101
|
|
83
|
-
|
102
|
+
See [the specification](https://api.abbyy.cloud/swagger/ui/index#!/Order/Order_TranslateSegments)
|
84
103
|
|
85
104
|
```ruby
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
error
|
91
|
-
end
|
92
|
-
|
93
|
-
error.class # => ABBYY::Cloud::ResponceError
|
94
|
-
error.status # => 400
|
105
|
+
result = CLIENT.mt.translate_segments(["To be", "or not to be"], from: :en, to: :ru)
|
106
|
+
|
107
|
+
result.class # => ABBYY::Cloud::Models::TranslationSequence
|
108
|
+
result.map(&:text) # => ["Быть", "или не быть"]
|
95
109
|
```
|
96
110
|
|
97
|
-
|
111
|
+
### Prices
|
112
|
+
|
113
|
+
The namespace `prices` contains operations with prices details.
|
114
|
+
|
115
|
+
#### details
|
116
|
+
|
117
|
+
See [the specification](https://api.abbyy.cloud/swagger/ui/index#!/Prices/Prices_GetAccountPrices).
|
98
118
|
|
99
119
|
```ruby
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
120
|
+
list = CLIENT.prices.details
|
121
|
+
|
122
|
+
list.first.to_h
|
123
|
+
# {
|
124
|
+
# id: "foo",
|
125
|
+
# account_id: "bar",
|
126
|
+
# type: "qux",
|
127
|
+
# from: "ru",
|
128
|
+
# to: "en",
|
129
|
+
# unit_prices: [{ unit_type: "Words", currency: "USD", amount: 0.03 }],
|
130
|
+
# discounts: [{ discount_type: "TMTextMatch", discount: 0.01 }],
|
131
|
+
# created: Time.now
|
107
132
|
# }
|
108
133
|
|
109
|
-
error.data.error # => "error message"
|
110
|
-
# etc.
|
111
134
|
```
|
112
135
|
|
136
|
+
The number of items can be several thousands. You can specify `skip` and `take` options to take necessary items only, otherwise it will return all prices.
|
137
|
+
|
138
|
+
Notice, though, that every single request can return no more than 1000 items. If you request more prices, several requests will be made one-by-one. Parsing all the results can be pretty slow.
|
139
|
+
|
113
140
|
## Compatibility
|
114
141
|
|
115
142
|
[WIP] Compatible to [ABBYY Cloud API v.0][abbyy-api].
|
data/abbyy-cloud.gemspec
CHANGED
data/lib/abbyy/cloud.rb
CHANGED
@@ -11,22 +11,12 @@ module ABBYY
|
|
11
11
|
require_relative "cloud/connection"
|
12
12
|
require_relative "cloud/settings"
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
require_relative "cloud/models/direction"
|
21
|
-
require_relative "cloud/models/engine"
|
22
|
-
|
23
|
-
require_relative "cloud/operations/base"
|
24
|
-
require_relative "cloud/operations/translate"
|
25
|
-
require_relative "cloud/operations/engines"
|
26
|
-
|
27
|
-
require_relative "cloud/namespaces/base"
|
28
|
-
require_relative "cloud/namespaces/orders"
|
29
|
-
require_relative "cloud/namespaces/machine_translations"
|
14
|
+
Dir[
|
15
|
+
"lib/abbyy/cloud/exceptions/*.rb",
|
16
|
+
"lib/abbyy/cloud/models/*.rb",
|
17
|
+
"lib/abbyy/cloud/operations/*.rb",
|
18
|
+
"lib/abbyy/cloud/namespaces/*.rb"
|
19
|
+
].each { |f| require File.expand_path(f) }
|
30
20
|
|
31
21
|
attr_reader :settings
|
32
22
|
|
@@ -38,6 +28,10 @@ module ABBYY
|
|
38
28
|
Namespaces::Orders.new(settings)
|
39
29
|
end
|
40
30
|
|
31
|
+
def prices
|
32
|
+
Namespaces::Prices.new(settings)
|
33
|
+
end
|
34
|
+
|
41
35
|
private
|
42
36
|
|
43
37
|
def initialize(*args)
|
@@ -7,35 +7,49 @@
|
|
7
7
|
class ABBYY::Cloud
|
8
8
|
class Connection
|
9
9
|
include Dry::Initializer.define -> do
|
10
|
-
option :version
|
11
10
|
option :id
|
12
11
|
option :token
|
13
12
|
end
|
14
13
|
|
15
|
-
|
16
|
-
uri = root.merge(path).tap { |item| item.scheme = "https" }
|
17
|
-
req = prepare_request(http_method, uri, JSON(body.to_h), headers.to_h)
|
14
|
+
attr_reader :root
|
18
15
|
|
19
|
-
|
20
|
-
|
16
|
+
def call(http_method, path, **options)
|
17
|
+
uri = prepare_uri(path, options)
|
18
|
+
req = Net::HTTP.const_get(http_method.capitalize).new(uri)
|
19
|
+
setup_headers(req, options)
|
20
|
+
setup_body(req, options)
|
21
|
+
|
22
|
+
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
23
|
+
http.request(req)
|
21
24
|
end
|
25
|
+
handle_response(res)
|
22
26
|
end
|
23
27
|
|
24
28
|
private
|
25
29
|
|
26
|
-
def
|
27
|
-
|
30
|
+
def initialize(*)
|
31
|
+
super
|
32
|
+
@root = URI("https://api.abbyy.cloud").tap { |obj| obj.scheme = "https" }
|
28
33
|
end
|
29
34
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
def prepare_uri(path, query: nil, **)
|
36
|
+
uri = root.merge(path)
|
37
|
+
query = query.to_h.map { |k, v| "#{k}=#{v}" if v }.compact.join("&")
|
38
|
+
uri.query = query unless query.empty?
|
39
|
+
uri
|
40
|
+
end
|
41
|
+
|
42
|
+
def setup_headers(req, headers: nil, **)
|
43
|
+
req.basic_auth id, token
|
44
|
+
req["accept-charset"] = "utf-8"
|
45
|
+
req["accept"] = "application/json"
|
46
|
+
req["content-type"] = "application/json"
|
47
|
+
headers.to_h.each { |key, value| req[key.to_s] = value }
|
48
|
+
end
|
49
|
+
|
50
|
+
def setup_body(req, body: nil, **)
|
51
|
+
return unless req["content-type"] == "application/json"
|
52
|
+
req.body = JSON(body.to_h)
|
39
53
|
end
|
40
54
|
|
41
55
|
def handle_response(response)
|
@@ -1,9 +1,11 @@
|
|
1
|
+
require_relative "locale"
|
2
|
+
|
1
3
|
class ABBYY::Cloud
|
2
4
|
module Models
|
3
5
|
# Description of the translation direction
|
4
6
|
class Direction < Struct
|
5
|
-
attribute :source, Types::
|
6
|
-
attribute :target, Types::
|
7
|
+
attribute :source, Types::Locale
|
8
|
+
attribute :target, Types::Locale
|
7
9
|
end
|
8
10
|
|
9
11
|
# Registers type Types::Direction
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class ABBYY::Cloud
|
2
|
+
module Models
|
3
|
+
# Description of the price discount
|
4
|
+
class Discount < Struct
|
5
|
+
attribute :discount_type, Types::DiscountType
|
6
|
+
attribute :discount, Types::Coercible::Float
|
7
|
+
end
|
8
|
+
|
9
|
+
# Registers type Types::Discount
|
10
|
+
Types.register_type Discount
|
11
|
+
end
|
12
|
+
end
|
@@ -1,10 +1,13 @@
|
|
1
|
+
require_relative "locale"
|
2
|
+
require_relative "direction"
|
3
|
+
|
1
4
|
class ABBYY::Cloud
|
2
5
|
# Collection of models returned in requests
|
3
6
|
module Models
|
4
7
|
# Description of the engine
|
5
8
|
class Engine < Struct
|
6
9
|
attribute :name, Types::Strict::String
|
7
|
-
attribute :languages, Types::Array.member(Types::
|
10
|
+
attribute :languages, Types::Array.member(Types::Locale)
|
8
11
|
attribute :translation_directions, Types::Array.member(Types::Direction)
|
9
12
|
end
|
10
13
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ABBYY::Cloud
|
2
|
+
module Models
|
3
|
+
class Locale < String
|
4
|
+
FORMAT = /\A[A-Za-z0-9]{2,}(-[A-Za-z0-9]+)*\z|\A[i|x](-[A-Za-z0-9]+)+\z/
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def new(value)
|
8
|
+
return unless value
|
9
|
+
return super if value[FORMAT]
|
10
|
+
raise <<-MESSAGE.gsub(" +\|", "")
|
11
|
+
|'#{value}' is not a valid locale. See:
|
12
|
+
| RFC-5656 (https://tools.ietf.org/html/rfc5646) for valid format
|
13
|
+
| Full list of locales at http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
|
14
|
+
MESSAGE
|
15
|
+
end
|
16
|
+
alias_method :[], :new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Registers type Types::Locale
|
21
|
+
Types.register_type Locale
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative "locale"
|
2
|
+
require_relative "unit_price"
|
3
|
+
require_relative "discount"
|
4
|
+
|
5
|
+
class ABBYY::Cloud
|
6
|
+
module Models
|
7
|
+
# Price details
|
8
|
+
class Price < Struct
|
9
|
+
attribute :id, Types::Strict::String
|
10
|
+
attribute :account_id, Types::Strict::String
|
11
|
+
attribute :type, Types::Strict::String
|
12
|
+
attribute :from, Types::Locale
|
13
|
+
attribute :to, Types::Locale
|
14
|
+
attribute :unit_prices, Types::Array.member(Types::UnitPrice)
|
15
|
+
attribute :discounts, Types::Array.member(Types::Discount)
|
16
|
+
attribute :created, Types::Coercible::Time
|
17
|
+
end
|
18
|
+
|
19
|
+
# Registers type Types::Price
|
20
|
+
Types.register_type Price
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative "source_tag"
|
2
|
+
|
3
|
+
class ABBYY::Cloud
|
4
|
+
module Models
|
5
|
+
# A segment for the translation
|
6
|
+
class SourceSegment < Struct
|
7
|
+
attribute :text, Types::Strict::String
|
8
|
+
attribute :tags, Types::Array.member(Types::SourceTag).default([])
|
9
|
+
end
|
10
|
+
|
11
|
+
# Registers type Types::SourceSegment
|
12
|
+
Types.register_type SourceSegment
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class ABBYY::Cloud
|
2
|
+
module Models
|
3
|
+
TYPES = %w(Start End Placeholder).freeze
|
4
|
+
|
5
|
+
# Tag for translation source/target
|
6
|
+
class SourceTag < Struct
|
7
|
+
attribute :number, Types::Strict::Int
|
8
|
+
attribute :position, Types::Strict::Int
|
9
|
+
attribute :type, Types::Strict::String.constrained(included_in: TYPES)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Registers type Types::SourceTag
|
13
|
+
Types.register_type SourceTag
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class ABBYY::Cloud
|
2
|
+
module Models
|
3
|
+
TYPES = %w(Start End Placeholder).freeze
|
4
|
+
|
5
|
+
# Tag for translation source/target
|
6
|
+
class TransferData < Struct
|
7
|
+
attribute :position, Types::Strict::Int
|
8
|
+
attribute :order, Types::Strict::Int
|
9
|
+
end
|
10
|
+
|
11
|
+
# Registers type Types::TransferData
|
12
|
+
Types.register_type TransferData
|
13
|
+
end
|
14
|
+
end
|