rev-api 2.2.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +22 -21
  3. data/.ruby-gemset +1 -1
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +8 -8
  6. data/Gemfile +3 -3
  7. data/LICENSE +191 -191
  8. data/README.md +131 -132
  9. data/Rakefile +13 -13
  10. data/examples/cli.rb +270 -270
  11. data/lib/rev-api.rb +26 -26
  12. data/lib/rev-api/api.rb +326 -326
  13. data/lib/rev-api/api_serializable.rb +30 -30
  14. data/lib/rev-api/exceptions.rb +97 -100
  15. data/lib/rev-api/http_client.rb +97 -97
  16. data/lib/rev-api/models/order.rb +129 -138
  17. data/lib/rev-api/models/order_request.rb +273 -222
  18. data/lib/rev-api/version.rb +3 -3
  19. data/rev-api.gemspec +33 -34
  20. data/spec/fixtures/api_cassettes/cancel_order.yml +38 -38
  21. data/spec/fixtures/api_cassettes/cancel_order_not_allowed.yml +40 -40
  22. data/spec/fixtures/api_cassettes/get_attachment_content.yml +399 -399
  23. data/spec/fixtures/api_cassettes/get_attachment_content_as_pdf.yml +399 -399
  24. data/spec/fixtures/api_cassettes/get_attachment_content_as_text.yml +65 -65
  25. data/spec/fixtures/api_cassettes/get_attachment_content_as_youtube_transcript.yml +66 -66
  26. data/spec/fixtures/api_cassettes/get_attachment_content_unacceptable_representation.yml +42 -42
  27. data/spec/fixtures/api_cassettes/get_attachment_content_with_invalid_id.yml +42 -42
  28. data/spec/fixtures/api_cassettes/get_attachment_metadata.yml +42 -42
  29. data/spec/fixtures/api_cassettes/get_attachment_with_invalid_id.yml +40 -40
  30. data/spec/fixtures/api_cassettes/get_orders.yml +122 -122
  31. data/spec/fixtures/api_cassettes/get_orders_with_clientRef.yml +41 -41
  32. data/spec/fixtures/api_cassettes/get_tc_order.yml +44 -44
  33. data/spec/fixtures/api_cassettes/get_third_page_of_orders.yml +52 -58
  34. data/spec/fixtures/api_cassettes/link_input.yml +44 -44
  35. data/spec/fixtures/api_cassettes/link_input_with_all_attributes.yml +44 -44
  36. data/spec/fixtures/api_cassettes/link_input_with_spaces_in_filename.yml +45 -45
  37. data/spec/fixtures/api_cassettes/not_found_order.yml +42 -42
  38. data/spec/fixtures/api_cassettes/submit_cp_order.yml +44 -45
  39. data/spec/fixtures/api_cassettes/submit_su_order.yml +44 -45
  40. data/spec/fixtures/api_cassettes/submit_tc_order_with_account_balance.yml +44 -45
  41. data/spec/fixtures/api_cassettes/submit_tc_order_with_invalid_request.yml +45 -45
  42. data/spec/fixtures/api_cassettes/submit_tc_order_without_specifying_payment.yml +44 -45
  43. data/spec/fixtures/api_cassettes/unauthorized.yml +42 -42
  44. data/spec/fixtures/api_cassettes/upload_input.yml +90 -90
  45. data/spec/fixtures/api_cassettes/upload_input_with_invalid_content_type.yml +91 -91
  46. data/spec/lib/rev/api_spec.rb +30 -24
  47. data/spec/lib/rev/cancel_order_spec.rb +24 -24
  48. data/spec/lib/rev/exceptions_spec.rb +8 -8
  49. data/spec/lib/rev/get_attachment_content_spec.rb +79 -79
  50. data/spec/lib/rev/get_attachment_metadata_spec.rb +33 -33
  51. data/spec/lib/rev/get_order_spec.rb +52 -68
  52. data/spec/lib/rev/get_orders_spec.rb +62 -62
  53. data/spec/lib/rev/http_client_spec.rb +32 -32
  54. data/spec/lib/rev/models/order_request_spec.rb +79 -10
  55. data/spec/lib/rev/models/order_spec.rb +58 -58
  56. data/spec/lib/rev/post_inputs_spec.rb +94 -94
  57. data/spec/lib/rev/post_order_spec.rb +163 -195
  58. data/spec/spec_helper.rb +47 -49
  59. data/spec/test_helpers.rb +5 -0
  60. metadata +10 -28
  61. data/.coveralls.yml +0 -2
  62. data/spec/fixtures/api_cassettes/get_tr_order.yml +0 -44
  63. data/spec/fixtures/api_cassettes/submit_tr_order.yml +0 -44
@@ -1,138 +1,129 @@
1
- require 'rev-api/api_serializable'
2
-
3
- module Rev
4
- # Represents Translation, Caption, or Transcription order.
5
- # Should have TranslationInfo, CaptionInfo, or TranscriptionInfo, list
6
- # of comments and attachments. Attributes names reflect
7
- # API exposed names, but occasional hyphens are replaced
8
- # with underscores
9
- class Order < ApiSerializable
10
- attr_reader :order_number, :price, :status, :attachments, :comments,
11
- :translation, :transcription, :caption, :client_ref
12
-
13
- # @param fields [Hash] hash of order fields parsed from JSON API response
14
- def initialize(fields)
15
- super fields
16
- @attachments = fields['attachments'].map { |attachment_fields| Attachment.new(attachment_fields) }
17
- @comments = fields['comments'].map { |comment_fields| Comment.new(comment_fields) }
18
- @translation = TranslationInfo.new(fields['translation']) if fields['translation']
19
- @transcription = TranscriptionInfo.new(fields['transcription']) if fields['transcription']
20
- @caption = CaptionInfo.new(fields['caption']) if fields['caption']
21
- end
22
-
23
- # @return [Array of Attachment] with the kind of "transcript"
24
- def transcripts
25
- @attachments.select { |a| a.kind == Attachment::KINDS[:transcript]}
26
- end
27
-
28
- # @return [Array of Attachment] with the kind of "translation"
29
- def translations
30
- @attachments.select { |a| a.kind == Attachment::KINDS[:translation]}
31
- end
32
-
33
- # @return [Array of Attachment] with the kind of "caption"
34
- def captions
35
- @attachments.select { |a| a.kind == Attachment::KINDS[:caption] }
36
- end
37
-
38
- # @return [Array of Attachment] with the kind of "sources"
39
- def sources
40
- @attachments.select { |a| a.kind == Attachment::KINDS[:media]}
41
- end
42
- end
43
-
44
- # Order comment, containing author, creation timestamp and text
45
- class Comment < ApiSerializable
46
- require 'date'
47
-
48
- attr_reader :by, :timestamp, :text
49
-
50
- # @param fields [Hash] hash of comment fields parsed from JSON API response
51
- def initialize(fields)
52
- super fields
53
- @timestamp = Date.iso8601(fields['timestamp'])
54
- @text = fields['text'] ? fields['text'] : String.new # right now API gives no 'text' field if text is empty
55
- end
56
- end
57
-
58
- # Additional information specific to translation orders,
59
- # such as word count, languages
60
- class TranslationInfo < ApiSerializable
61
- attr_reader :total_word_count, :source_language_code,
62
- :destination_language_code
63
- end
64
-
65
- # Additional information specific to transcription orders,
66
- # such as total length in minutes, verbatim and timestamps flags
67
- class TranscriptionInfo < ApiSerializable
68
- attr_reader :total_length_seconds, :verbatim, :timestamps
69
-
70
- # @deprecated use :total_length_seconds instead
71
- attr_reader :total_length
72
- end
73
-
74
- # Additional information specific to caption orders
75
- class CaptionInfo < ApiSerializable
76
- attr_reader :total_length_seconds
77
-
78
- # @deprecated use :total_length_seconds instead
79
- attr_reader :total_length
80
- end
81
-
82
- # Represents order attachment - logical document associated with order
83
- class Attachment < ApiSerializable
84
- attr_reader :kind, :name, :id, :audio_length_seconds, :word_count, :links, :video_length_seconds
85
-
86
- KINDS = {
87
- :transcript => 'transcript',
88
- :translation => 'translation',
89
- :caption => 'caption',
90
- :media => 'media'
91
- }
92
-
93
- # List of supported mime-types used to request attachment's content
94
- # within 'Accept' header
95
- REPRESENTATIONS = {
96
- # Supported by :transcript and :translation
97
- :docx => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
98
- :doc => 'application/msword',
99
- :pdf => 'application/pdf',
100
- :txt => 'text/plain',
101
- :youtube => 'text/plain; format=youtube-transcript',
102
-
103
- # Supported by :caption
104
- :srt => 'application/x-subrip',
105
- :scc => 'text/x-scc',
106
- :ttml => 'application/ttml+xml',
107
- :qt => 'application/x-quicktime-timedtext'
108
- }
109
-
110
- # @param fields [Hash] fields of attachment fields parsed from JSON API response
111
- def initialize(fields)
112
- super fields
113
- @links = fields['links'].map { |link_fields| Link.new(link_fields) }
114
- end
115
-
116
- # @param ext [Symbol] extension
117
- # @return [String] mime-type for requested extension
118
- def self.representation_mime(ext)
119
- REPRESENTATIONS[ext]
120
- end
121
- end
122
-
123
- # Link to actual file represented by attachment
124
- class Link < ApiSerializable
125
- attr_reader :rel, :href, :content_type
126
- end
127
-
128
- # Represents a paginated list of orders, including padination info.
129
- class OrdersListPage < ApiSerializable
130
- attr_reader :total_count, :results_per_page, :page, :orders
131
-
132
- # @param fields [Hash] hash of OrdersListPage fields parsed from JSON API response
133
- def initialize(fields)
134
- super fields
135
- @orders = fields['orders'].map { |order_fields| Order.new(order_fields) }
136
- end
137
- end
138
- end
1
+ require 'rev-api/api_serializable'
2
+
3
+ module Rev
4
+ # Represents a Caption or Transcription order.
5
+ # Should have CaptionInfo or TranscriptionInfo, list
6
+ # of comments and attachments. Attributes names reflect
7
+ # API exposed names, but occasional hyphens are replaced
8
+ # with underscores
9
+ class Order < ApiSerializable
10
+ attr_reader :order_number, :price, :status, :attachments, :comments,
11
+ :transcription, :caption, :client_ref
12
+
13
+ # @param fields [Hash] hash of order fields parsed from JSON API response
14
+ def initialize(fields)
15
+ super fields
16
+ @attachments = fields['attachments'].map { |attachment_fields| Attachment.new(attachment_fields) }
17
+ @comments = fields['comments'].map { |comment_fields| Comment.new(comment_fields) }
18
+ @transcription = TranscriptionInfo.new(fields['transcription']) if fields['transcription']
19
+ @caption = CaptionInfo.new(fields['caption']) if fields['caption']
20
+ end
21
+
22
+ # @return [Array of Attachment] with the kind of "transcript"
23
+ def transcripts
24
+ @attachments.select { |a| a.kind == Attachment::KINDS[:transcript]}
25
+ end
26
+
27
+ # @return [Array of Attachment] with the kind of "caption"
28
+ def captions
29
+ @attachments.select { |a| a.kind == Attachment::KINDS[:caption] }
30
+ end
31
+
32
+ # @return [Array of Attachment] with the kind of "sources"
33
+ def sources
34
+ @attachments.select { |a| a.kind == Attachment::KINDS[:media]}
35
+ end
36
+ end
37
+
38
+ # Order comment, containing author, creation timestamp and text
39
+ class Comment < ApiSerializable
40
+ require 'date'
41
+
42
+ attr_reader :by, :timestamp, :text
43
+
44
+ # @param fields [Hash] hash of comment fields parsed from JSON API response
45
+ def initialize(fields)
46
+ super fields
47
+ @timestamp = Date.iso8601(fields['timestamp'])
48
+ @text = fields['text'] ? fields['text'] : String.new # right now API gives no 'text' field if text is empty
49
+ end
50
+ end
51
+
52
+ # Additional information specific to transcription orders,
53
+ # such as total length in minutes, verbatim and timestamps flags
54
+ class TranscriptionInfo < ApiSerializable
55
+ attr_reader :total_length_seconds, :verbatim, :timestamps
56
+
57
+ # @deprecated use :total_length_seconds instead
58
+ attr_reader :total_length
59
+ end
60
+
61
+ # Additional information specific to caption orders
62
+ class CaptionInfo < ApiSerializable
63
+ attr_reader :total_length_seconds
64
+
65
+ # @deprecated use :total_length_seconds instead
66
+ attr_reader :total_length
67
+ end
68
+
69
+ # Represents order attachment - logical document associated with order
70
+ class Attachment < ApiSerializable
71
+ attr_reader :kind, :name, :id, :audio_length_seconds, :links, :video_length_seconds
72
+
73
+ KINDS = {
74
+ :transcript => 'transcript',
75
+ :caption => 'caption',
76
+ :media => 'media'
77
+ }
78
+
79
+ # List of supported mime-types used to request attachment's content
80
+ # within 'Accept' header
81
+ REPRESENTATIONS = {
82
+ # Supported by :transcript
83
+ :docx => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
84
+ :pdf => 'application/pdf',
85
+ :txt => 'text/plain',
86
+ :youtube => 'text/plain; format=youtube-transcript',
87
+
88
+ # Supported by :caption
89
+ :srt => 'application/x-subrip',
90
+ :scc => 'text/x-scc',
91
+ :mcc => 'text/x-mcc',
92
+ :ttml => 'application/ttml+xml',
93
+ :qt => 'application/x-quicktime-timedtext',
94
+ :vtt => 'text/vtt',
95
+ :dfxp => 'application/ttaf+xml',
96
+ :cap => 'application/x-cheetah-cap',
97
+ :stl => 'text/x-stl',
98
+ :avidds => 'text/vnd.avid-ds'
99
+ }
100
+
101
+ # @param fields [Hash] fields of attachment fields parsed from JSON API response
102
+ def initialize(fields)
103
+ super fields
104
+ @links = fields['links'].map { |link_fields| Link.new(link_fields) }
105
+ end
106
+
107
+ # @param ext [Symbol] extension
108
+ # @return [String] mime-type for requested extension
109
+ def self.representation_mime(ext)
110
+ REPRESENTATIONS[ext]
111
+ end
112
+ end
113
+
114
+ # Link to actual file represented by attachment
115
+ class Link < ApiSerializable
116
+ attr_reader :rel, :href, :content_type
117
+ end
118
+
119
+ # Represents a paginated list of orders, including padination info.
120
+ class OrdersListPage < ApiSerializable
121
+ attr_reader :total_count, :results_per_page, :page, :orders
122
+
123
+ # @param fields [Hash] hash of OrdersListPage fields parsed from JSON API response
124
+ def initialize(fields)
125
+ super fields
126
+ @orders = fields['orders'].map { |order_fields| Order.new(order_fields) }
127
+ end
128
+ end
129
+ end
@@ -1,222 +1,273 @@
1
- require 'rev-api/api_serializable'
2
-
3
- module Rev
4
- # OrderRequest is used for constructing order 'spec' in consumer code and passing it into.
5
- # It consists of three main elements: :payment, :transcription_options and :notification.
6
- # You can also supply reference number, customer comment, and whether standard turnaround time is not required
7
- #
8
- # @note https://www.rev.com/api/ordersposttranscription, https://www.rev.com/api/ordersposttranslation, https://www.rev.com/api/orderspostcaption
9
- class OrderRequest < ApiSerializable
10
- # see {Rev::Payment}
11
- attr_reader :payment
12
-
13
- # see {Rev::TranscriptionOptions}
14
- attr_reader :transcription_options
15
-
16
- # see {Rev::TranslationOptions}
17
- attr_reader :translation_options
18
-
19
- # see {Rev::CaptionOptions}
20
- attr_reader :caption_options
21
-
22
- # see {Rev::Notification}
23
- attr_reader :notification
24
-
25
- # a reference number for the order meaningful for the client (optional)
26
- attr_reader :client_ref
27
-
28
- # a comment with any special messages about the order (optional)
29
- attr_reader :comment
30
-
31
- # a boolean flag specifying whether normal turnaround time is not required, defaults to false (optional)
32
- attr_reader :non_standard_tat_guarantee
33
-
34
- # @param payment [Payment] payment info
35
- # @param fields [Hash] of fields to initialize instance. See instance attributes for available fields.
36
- # @deprecated payment always defaults to :account_balance
37
- def self.new_with_payment(payment, fields = {})
38
- fields = { :non_standard_tat_guarantee => false }.merge(fields)
39
- super fields
40
- @payment = payment
41
- end
42
-
43
- # @param fields [Hash] of fields to initialize instance. See instance attributes for available fields.
44
- def initialize(fields = {})
45
- fields = { :non_standard_tat_guarantee => false }.merge(fields)
46
- @payment = Rev::Payment.with_account_balance
47
- super fields
48
- end
49
- end
50
-
51
- # Payment Info. Payment can only be done by debiting the user's account balance.
52
- # @deprecated setting the payment is no longer necessary. All orders now default to :account_balance
53
- class Payment < ApiSerializable
54
- attr_accessor :type
55
-
56
- # use to correctly set payment type
57
- TYPES = {
58
- :account_balance => 'AccountBalance'
59
- }
60
-
61
- CC_ON_FILE_ID = 1
62
-
63
- # @param type [String] payment method
64
- def initialize(type)
65
- @type = type
66
- end
67
-
68
- class << self
69
- def with_account_balance()
70
- Payment::new(TYPES[:account_balance])
71
- end
72
- end
73
- end
74
-
75
- # Billing address
76
- class BillingAddress < ApiSerializable
77
- attr_reader :street, :street2, :city, :state, :zip, :country_alpha2
78
- end
79
-
80
- # Superclass for the business-line options that handles capture and common validation of inputs.
81
- class InputOptions < ApiSerializable
82
- # Mandatory, contains list of inputs. Must have at least one element.
83
- attr_reader :inputs
84
-
85
- # @param inputs [Array] list of inputs
86
- # @param info [Hash] of fields to initialize instance.
87
- def initialize(inputs, info = {})
88
- super info
89
- raise(ArgumentError, "inputs must have at least one element") unless validate_inputs(inputs)
90
- @inputs = inputs
91
- end
92
-
93
- private
94
-
95
- def validate_inputs(inputs)
96
- !inputs.nil? && inputs.length > 0
97
- end
98
- end
99
-
100
- # Transcription options. This section contains the input media that must be transferred to our servers
101
- # using a POST to /inputs, and are referenced using the URIs returned by that call. We also support external links.
102
- # @see https://www.rev.com/api/ordersposttranscription
103
- class TranscriptionOptions < InputOptions
104
- # Optional, should we transcribe the provided files verbatim? If true,
105
- # all filler words (i.e. umm, huh) will be included.
106
- attr_reader :verbatim
107
-
108
- # Optional, should we include timestamps?
109
- attr_reader :timestamps
110
-
111
- # @param inputs [Array] list of inputs
112
- # @param info [Hash] of fields to initialize instance. May contain:
113
- # - :verbatim => true/false
114
- # - :timestamps => true/false
115
- def initialize(inputs, info = {})
116
- super inputs, info
117
- end
118
- end
119
-
120
- # Translation options. This section contains the input media that must be transferred to our
121
- # servers using a POST to /inputs, and are referenced using the URIs returned by that call.
122
- # For each media, word count must be specified. The language code for the source and desitination
123
- # languages must also be specified.
124
- # @see https://www.rev.com/api/ordersposttranslation
125
- class TranslationOptions < InputOptions
126
- # Mandatory, source language code
127
- attr_reader :source_language_code
128
-
129
- # Mandatory, destination language code
130
- attr_reader :destination_language_code
131
-
132
- # @param inputs [Array] list of inputs
133
- # @param info [Hash] of fields to initialize instance. May contain:
134
- # - :source_language_code
135
- # - :destination_language_code
136
- # @note For language codes refer to http://www.loc.gov/standards/iso639-2/php/code_list.php
137
- def initialize(inputs, info = {})
138
- super inputs, info
139
- end
140
- end
141
-
142
- # Caption options. This section contains the input media that must be transferred to our servers
143
- # using a POST to /inputs, and are referenced using the URIs returned by that call. We also support external links.
144
- # @see https://www.rev.com/api/orderspostcaption
145
- class CaptionOptions < InputOptions
146
- # Array of file formats the captions should be delivered as. (Optional, default is SubRip)
147
- attr_reader :output_file_formats
148
-
149
- # Optional, Array of language codes to request foreign language subtitles
150
- attr_reader :subtitle_languages
151
-
152
- # All supported output file formats
153
- OUTPUT_FILE_FORMATS = {
154
- :subrip => 'SubRip',
155
- :scc => 'Scc',
156
- :mcc => 'Mcc',
157
- :ttml => 'Ttml',
158
- :qttext => 'QTtext',
159
- :transcript => 'Transcript',
160
- :webvtt => 'WebVtt',
161
- :dfxp => 'Dfxp',
162
- :cheetahcap => 'CheetahCap'
163
- }
164
-
165
- # @param inputs [Array] list of inputs
166
- # @param info [Hash] of fields to initialize instance. May contain:
167
- # - :subtitle_languages
168
- # @see TranslationOptions for a list of language codes.
169
- def initialize(inputs, info = {})
170
- super(inputs, info)
171
- raise(ArgumentError, "invalid format(s)") unless validate_output_formats(info[:output_file_formats])
172
- end
173
-
174
- private
175
-
176
- def validate_output_formats(formats)
177
- formats.nil? || formats.select{|f| !OUTPUT_FILE_FORMATS.has_value?(f) }.empty?
178
- end
179
- end
180
-
181
- # Input for order (aka source file)
182
- class Input < ApiSerializable
183
- # Mandatory when used with {Rev::OrderRequest::TranslationInfo}, length of document, in words
184
- attr_reader :word_length
185
-
186
- # Length of audio in seconds (mandatory in case of inability to determine it automatically).
187
- # Used within {Rev::OrderRequest::TranscriptionInfo}
188
- attr_reader :audio_length_seconds
189
-
190
- # Length of video in seconds (mandatory in case of inability to determine it automatically).
191
- # Used within {Rev::OrderRequest::CaptionInfo}
192
- attr_reader :video_length_seconds
193
-
194
- # Mandatory, URI of the media, as returned from the call to POST /inputs.
195
- # :external_link might substitute :uri for Transcription or Caption.
196
- attr_reader :uri
197
-
198
- # External URL, if sources wasn't POSTed as input (YouTube, Vimeo, Dropbox, etc)
199
- attr_reader :external_link
200
- end
201
-
202
- # Notification Info. Optionally you may request that an HTTP post be made to a url of your choice when the order enters
203
- # a new status (eg being transcribed or reviewed) and when it is complete.
204
- class Notification < ApiSerializable
205
- attr_reader :url, :level
206
-
207
- # Notification levels
208
- LEVELS = {
209
- :detailed => 'Detailed',
210
- :final_only => 'FinalOnly'
211
- }
212
-
213
- # @param url [String] The url for notifications. Mandatory if the notifications element is used. Updates will be posted to this URL
214
- # @param level [String] Optional, specifies which notifications are sent:
215
- # - :detailed - a notification is sent whenever the order is in a new status or has a new comment
216
- # - :final_only - (the default), notification is sent only when the order is complete
217
- def initialize(url, level = nil)
218
- @url = url
219
- @level = level ? level : LEVELS[:final_only]
220
- end
221
- end
222
- end
1
+ require 'rev-api/api_serializable'
2
+
3
+ module Rev
4
+ # OrderRequest is used for constructing order 'spec' in consumer code and passing it into.
5
+ # It consists of three main elements: :payment, :transcription_options and :notification.
6
+ # You can also supply reference number and whether standard turnaround time is not required
7
+ #
8
+ # @note https://www.rev.com/api/ordersposttranscription, https://www.rev.com/api/orderspostcaption
9
+
10
+ GLOSSARY_ENTRIES_LIMIT = 1000
11
+ GLOSSARY_ENTRY_LENGTH_LIMIT = 255
12
+ SPEAKER_ENTRIES_LIMIT = 100
13
+ SPEAKER_ENTRY_LENGTH_LIMIT = 15
14
+
15
+ class OrderRequest < ApiSerializable
16
+ # see {Rev::Payment}
17
+ attr_reader :payment
18
+
19
+ # see {Rev::TranscriptionOptions}
20
+ attr_reader :transcription_options
21
+
22
+ # see {Rev::CaptionOptions}
23
+ attr_reader :caption_options
24
+
25
+ # see {Rev::Notification}
26
+ attr_reader :notification
27
+
28
+ # a reference number for the order meaningful for the client (optional)
29
+ attr_reader :client_ref
30
+
31
+ # a boolean flag specifying whether normal turnaround time is not required, defaults to false (optional)
32
+ attr_reader :non_standard_tat_guarantee
33
+
34
+ # @param payment [Payment] payment info
35
+ # @param fields [Hash] of fields to initialize instance. See instance attributes for available fields.
36
+ # @deprecated payment always defaults to :account_balance
37
+ def self.new_with_payment(payment, fields = {})
38
+ fields = { :non_standard_tat_guarantee => false }.merge(fields)
39
+ super fields
40
+ @payment = payment
41
+ end
42
+
43
+ # @param fields [Hash] of fields to initialize instance. See instance attributes for available fields.
44
+ def initialize(fields = {})
45
+ fields = { :non_standard_tat_guarantee => false }.merge(fields)
46
+ @payment = Rev::Payment.with_account_balance
47
+ super fields
48
+ end
49
+ end
50
+
51
+ # Payment Info. Payment can only be done by debiting the user's account balance.
52
+ # @deprecated setting the payment is no longer necessary. All orders now default to :account_balance
53
+ class Payment < ApiSerializable
54
+ attr_accessor :type
55
+
56
+ # use to correctly set payment type
57
+ TYPES = {
58
+ :account_balance => 'AccountBalance'
59
+ }
60
+
61
+ CC_ON_FILE_ID = 1
62
+
63
+ # @param type [String] payment method
64
+ def initialize(type)
65
+ @type = type
66
+ end
67
+
68
+ class << self
69
+ def with_account_balance()
70
+ Payment::new(TYPES[:account_balance])
71
+ end
72
+ end
73
+ end
74
+
75
+ # Billing address
76
+ class BillingAddress < ApiSerializable
77
+ attr_reader :street, :street2, :city, :state, :zip, :country_alpha2
78
+ end
79
+
80
+ # Superclass for the business-line options that handles capture and common validation of inputs.
81
+ class InputOptions < ApiSerializable
82
+ # Mandatory, contains list of inputs. Must have at least one element.
83
+ attr_reader :inputs
84
+
85
+ # @param inputs [Array] list of inputs
86
+ # @param info [Hash] of fields to initialize instance.
87
+ def initialize(inputs, info = {})
88
+ super info
89
+ raise(ArgumentError, "inputs must have at least one element") unless validate_inputs(inputs)
90
+ @inputs = inputs
91
+ end
92
+
93
+ private
94
+
95
+ def validate_inputs(inputs)
96
+ !inputs.nil? && inputs.length > 0
97
+ end
98
+ end
99
+
100
+ # Transcription options. This section contains the input media that must be transferred to our servers
101
+ # using a POST to /inputs, and are referenced using the URIs returned by that call. We also support external links.
102
+ # @see https://www.rev.com/api/ordersposttranscription
103
+ class TranscriptionOptions < InputOptions
104
+ # Optional, should we transcribe the provided files verbatim? If true,
105
+ # all filler words (i.e. umm, huh) will be included.
106
+ attr_reader :verbatim
107
+
108
+ # Optional, should we include timestamps?
109
+ attr_reader :timestamps
110
+
111
+ # @param inputs [Array] list of inputs
112
+ # @param info [Hash] of fields to initialize instance. May contain:
113
+ # - :verbatim => true/false
114
+ # - :timestamps => true/false
115
+ def initialize(inputs, info = {})
116
+ super inputs, info
117
+ options_validation(inputs)
118
+ end
119
+
120
+ private
121
+
122
+ def options_validation(inputs)
123
+ inputs.each { |input|
124
+ input.validate_glossary
125
+ input.validate_speakers
126
+ input.validate_accents
127
+ }
128
+ end
129
+ end
130
+
131
+ # Caption options. This section contains the input media that must be transferred to our servers
132
+ # using a POST to /inputs, and are referenced using the URIs returned by that call. We also support external links.
133
+ # @see https://www.rev.com/api/orderspostcaption
134
+ class CaptionOptions < InputOptions
135
+ # Array of file formats the captions should be delivered as. (Optional, default is SubRip)
136
+ attr_reader :output_file_formats
137
+
138
+ # Optional, Array of language codes to request foreign language subtitles
139
+ attr_reader :subtitle_languages
140
+
141
+ # All supported output file formats
142
+ OUTPUT_FILE_FORMATS = {
143
+ :subrip => 'SubRip',
144
+ :scc => 'Scc',
145
+ :mcc => 'Mcc',
146
+ :ttml => 'Ttml',
147
+ :qttext => 'QTtext',
148
+ :transcript => 'Transcript',
149
+ :webvtt => 'WebVtt',
150
+ :dfxp => 'Dfxp',
151
+ :cheetahcap => 'CheetahCap'
152
+ }
153
+
154
+ # @param inputs [Array] list of inputs
155
+ # @param info [Hash] of fields to initialize instance. May contain:
156
+ # - :subtitle_languages
157
+ # @see For language codes refer to http://www.loc.gov/standards/iso639-2/php/code_list.php
158
+ def initialize(inputs, info = {})
159
+ super(inputs, info)
160
+ raise(ArgumentError, "invalid format(s)") unless validate_output_formats(info[:output_file_formats])
161
+ options_validation(inputs)
162
+ end
163
+
164
+ private
165
+
166
+ def validate_output_formats(formats)
167
+ formats.nil? || formats.select{|f| !OUTPUT_FILE_FORMATS.has_value?(f) }.empty?
168
+ end
169
+
170
+ def options_validation(inputs)
171
+ inputs.each { |input|
172
+ input.validate_glossary
173
+ input.validate_speakers
174
+ }
175
+ end
176
+ end
177
+
178
+ # Input for order (aka source file)
179
+ class Input < ApiSerializable
180
+ # Length of audio in seconds (mandatory in case of inability to determine it automatically).
181
+ # Used within {Rev::OrderRequest::TranscriptionInfo}
182
+ attr_reader :audio_length_seconds
183
+
184
+ # Length of video in seconds (mandatory in case of inability to determine it automatically).
185
+ # Used within {Rev::OrderRequest::CaptionInfo}
186
+ attr_reader :video_length_seconds
187
+
188
+ # Mandatory, URI of the media, as returned from the call to POST /inputs.
189
+ # :external_link might substitute :uri for Transcription or Caption.
190
+ attr_reader :uri
191
+
192
+ # External URL, if sources wasn't POSTed as input (YouTube, Vimeo, Dropbox, etc)
193
+ attr_reader :external_link
194
+
195
+ # Optional, list of glossary entries.
196
+ attr_reader :glossary
197
+
198
+ # Optional, list of speaker names.
199
+ attr_reader :speakers
200
+
201
+ # Optional, list of accents.
202
+ attr_reader :accents
203
+
204
+ SUPPORTED_ACCENTS = {
205
+ :american_neutral => 'AmericanNeutral',
206
+ :american_southern => 'AmericanSouthern',
207
+ :asian => 'Asian',
208
+ :australian => 'Australian',
209
+ :british => 'British',
210
+ :indian => 'Indian',
211
+ :other => 'Other',
212
+ :unknown => 'Unknown'
213
+ }
214
+
215
+ def validate_glossary
216
+ if glossary
217
+ if glossary.length > GLOSSARY_ENTRIES_LIMIT
218
+ raise(ArgumentError, "Glossary must not exceed #{GLOSSARY_ENTRIES_LIMIT} entries")
219
+ end
220
+ glossary.each { |term|
221
+ if term.length > GLOSSARY_ENTRY_LENGTH_LIMIT
222
+ raise(ArgumentError, "Glossary entries cannot exceed #{GLOSSARY_ENTRY_LENGTH_LIMIT} characters")
223
+ end
224
+ }
225
+ end
226
+ end
227
+
228
+ def validate_speakers
229
+ if speakers
230
+ if speakers.length > SPEAKER_ENTRIES_LIMIT
231
+ raise(ArgumentError, "Speaker list must not exceed #{SPEAKER_ENTRIES_LIMIT} entries")
232
+ end
233
+ speakers.each { |speaker|
234
+ if speaker.length > SPEAKER_ENTRY_LENGTH_LIMIT
235
+ raise(ArgumentError, "Speaker name cannot exceed #{SPEAKER_ENTRY_LENGTH_LIMIT} characters")
236
+ end
237
+ }
238
+ end
239
+ end
240
+
241
+ def validate_accents
242
+ if accents
243
+ if accents.length > SUPPORTED_ACCENTS.length
244
+ raise(ArgumentError, "Length of accents list cannot exceed number of supported accents.")
245
+ end
246
+ if accents.any?{ |accent| !Rev::Input::SUPPORTED_ACCENTS.has_value?(accent) }
247
+ raise(ArgumentError, 'Unsupported accent provided')
248
+ end
249
+ end
250
+ end
251
+ end
252
+
253
+ # Notification Info. Optionally you may request that an HTTP post be made to a url of your choice when the order enters
254
+ # a new status (eg being transcribed or reviewed) and when it is complete.
255
+ class Notification < ApiSerializable
256
+ attr_reader :url, :level
257
+
258
+ # Notification levels
259
+ LEVELS = {
260
+ :detailed => 'Detailed',
261
+ :final_only => 'FinalOnly'
262
+ }
263
+
264
+ # @param url [String] The url for notifications. Mandatory if the notifications element is used. Updates will be posted to this URL
265
+ # @param level [String] Optional, specifies which notifications are sent:
266
+ # - :detailed - a notification is sent whenever the order is in a new status or has a new comment
267
+ # - :final_only - (the default), notification is sent only when the order is complete
268
+ def initialize(url, level = nil)
269
+ @url = url
270
+ @level = level ? level : LEVELS[:final_only]
271
+ end
272
+ end
273
+ end