mindee 1.2.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.rubocop.yml +2 -2
- data/.yardopts +4 -0
- data/CHANGELOG.md +21 -0
- data/README.md +46 -23
- data/Rakefile +6 -1
- data/bin/mindee.rb +70 -61
- data/docs/ruby-api-builder.md +131 -0
- data/docs/ruby-getting-started.md +265 -0
- data/docs/ruby-invoice-ocr.md +261 -0
- data/docs/ruby-passport-ocr.md +156 -0
- data/docs/ruby-receipt-ocr.md +170 -0
- data/lib/mindee/client.rb +128 -93
- data/lib/mindee/document_config.rb +22 -154
- data/lib/mindee/geometry.rb +105 -8
- data/lib/mindee/http/endpoint.rb +80 -0
- data/lib/mindee/input/pdf_processing.rb +106 -0
- data/lib/mindee/input/sources.rb +97 -0
- data/lib/mindee/input.rb +3 -0
- data/lib/mindee/parsing/document.rb +31 -0
- data/lib/mindee/parsing/error.rb +22 -0
- data/lib/mindee/parsing/inference.rb +53 -0
- data/lib/mindee/parsing/page.rb +46 -0
- data/lib/mindee/parsing/prediction/base.rb +30 -0
- data/lib/mindee/{fields → parsing/prediction/common_fields}/amount.rb +5 -1
- data/lib/mindee/{fields → parsing/prediction/common_fields}/base.rb +16 -5
- data/lib/mindee/{fields → parsing/prediction/common_fields}/company_registration.rb +0 -0
- data/lib/mindee/{fields/datefield.rb → parsing/prediction/common_fields/date.rb} +0 -0
- data/lib/mindee/{fields → parsing/prediction/common_fields}/locale.rb +0 -0
- data/lib/mindee/{fields → parsing/prediction/common_fields}/payment_details.rb +0 -0
- data/lib/mindee/parsing/prediction/common_fields/position.rb +39 -0
- data/lib/mindee/{fields → parsing/prediction/common_fields}/tax.rb +7 -2
- data/lib/mindee/parsing/prediction/common_fields/text.rb +12 -0
- data/lib/mindee/parsing/prediction/common_fields.rb +11 -0
- data/lib/mindee/parsing/prediction/custom/custom_v1.rb +58 -0
- data/lib/mindee/{fields/custom_docs.rb → parsing/prediction/custom/fields.rb} +5 -5
- data/lib/mindee/parsing/prediction/eu/license_plate/license_plate_v1.rb +34 -0
- data/lib/mindee/parsing/prediction/fr/bank_account_details/bank_account_details_v1.rb +40 -0
- data/lib/mindee/parsing/prediction/fr/carte_vitale/carte_vitale_v1.rb +49 -0
- data/lib/mindee/parsing/prediction/fr/id_card/id_card_v1.rb +84 -0
- data/lib/mindee/parsing/prediction/invoice/invoice_line_item.rb +58 -0
- data/lib/mindee/parsing/prediction/invoice/invoice_v4.rb +216 -0
- data/lib/mindee/parsing/prediction/passport/passport_v1.rb +184 -0
- data/lib/mindee/parsing/prediction/receipt/receipt_v4.rb +84 -0
- data/lib/mindee/parsing/prediction/shipping_container/shipping_container_v1.rb +38 -0
- data/lib/mindee/parsing/prediction/us/bank_check/bank_check_v1.rb +70 -0
- data/lib/mindee/parsing/prediction.rb +12 -0
- data/lib/mindee/parsing.rb +4 -0
- data/lib/mindee/version.rb +1 -1
- data/mindee.gemspec +2 -1
- metadata +57 -24
- data/lib/mindee/documents/base.rb +0 -35
- data/lib/mindee/documents/custom.rb +0 -65
- data/lib/mindee/documents/financial_doc.rb +0 -135
- data/lib/mindee/documents/invoice.rb +0 -162
- data/lib/mindee/documents/passport.rb +0 -163
- data/lib/mindee/documents/receipt.rb +0 -109
- data/lib/mindee/documents.rb +0 -7
- data/lib/mindee/endpoint.rb +0 -105
- data/lib/mindee/fields/orientation.rb +0 -26
- data/lib/mindee/fields.rb +0 -11
- data/lib/mindee/inputs.rb +0 -153
- data/lib/mindee/response.rb +0 -27
@@ -0,0 +1,184 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mrz'
|
4
|
+
|
5
|
+
require_relative '../common_fields'
|
6
|
+
require_relative '../base'
|
7
|
+
|
8
|
+
# We need to do this disgusting thing to avoid the following error message:
|
9
|
+
# td3 line one does not match the required format (MRZ::InvalidFormatError)
|
10
|
+
#
|
11
|
+
# See:
|
12
|
+
# https://github.com/streetspotr/mrz/issues/2
|
13
|
+
# https://github.com/streetspotr/mrz/pull/3
|
14
|
+
#
|
15
|
+
MRZ::TD3Parser::FORMAT_ONE = %r{\A(.{2})(.{3})([^<]+)<(.*)\z}.freeze
|
16
|
+
|
17
|
+
module Mindee
|
18
|
+
module Prediction
|
19
|
+
# Passport document.
|
20
|
+
class PassportV1 < Prediction
|
21
|
+
# The country of issue.
|
22
|
+
# @return [Mindee::TextField]
|
23
|
+
attr_reader :country
|
24
|
+
# The passport number.
|
25
|
+
# @return [Mindee::TextField]
|
26
|
+
attr_reader :id_number
|
27
|
+
# The expiration date of the passport.
|
28
|
+
# @return [Mindee::DateField]
|
29
|
+
attr_reader :expiry_date
|
30
|
+
# The issuance date of the passport.
|
31
|
+
# @return [Mindee::DateField]
|
32
|
+
attr_reader :issuance_date
|
33
|
+
# The surname (last name) of the passport holder.
|
34
|
+
# @return [Mindee::TextField]
|
35
|
+
attr_reader :surname
|
36
|
+
# List of first (given) names of the passport holder.
|
37
|
+
# @return [Mindee::TextField]
|
38
|
+
attr_reader :given_names
|
39
|
+
# The full name of the passport holder.
|
40
|
+
# @return [Array<Mindee::TextField>]
|
41
|
+
attr_reader :full_name
|
42
|
+
# The date of birth of the passport holder.
|
43
|
+
# @return [Mindee::DateField]
|
44
|
+
attr_reader :birth_date
|
45
|
+
# The place of birth of the passport holder.
|
46
|
+
# @return [Mindee::TextField]
|
47
|
+
attr_reader :birth_place
|
48
|
+
# The sex or gender of the passport holder.
|
49
|
+
# @return [Mindee::TextField]
|
50
|
+
attr_reader :gender
|
51
|
+
# The value of the first MRZ line.
|
52
|
+
# @return [Mindee::TextField]
|
53
|
+
attr_reader :mrz1
|
54
|
+
# The value of the second MRZ line.
|
55
|
+
# @return [Mindee::TextField]
|
56
|
+
attr_reader :mrz2
|
57
|
+
# All the MRZ values combined.
|
58
|
+
# @return [Mindee::TextField]
|
59
|
+
attr_reader :mrz
|
60
|
+
|
61
|
+
# @param prediction [Hash]
|
62
|
+
# @param page_id [Integer, nil]
|
63
|
+
def initialize(prediction, page_id)
|
64
|
+
super
|
65
|
+
@country = TextField.new(prediction['country'], page_id)
|
66
|
+
@id_number = TextField.new(prediction['id_number'], page_id)
|
67
|
+
@birth_date = DateField.new(prediction['birth_date'], page_id)
|
68
|
+
@expiry_date = DateField.new(prediction['expiry_date'], page_id)
|
69
|
+
@issuance_date = DateField.new(prediction['issuance_date'], page_id)
|
70
|
+
@birth_place = TextField.new(prediction['birth_place'], page_id)
|
71
|
+
@gender = TextField.new(prediction['gender'], page_id)
|
72
|
+
@surname = TextField.new(prediction['surname'], page_id)
|
73
|
+
@mrz1 = TextField.new(prediction['mrz1'], page_id)
|
74
|
+
@mrz2 = TextField.new(prediction['mrz2'], page_id)
|
75
|
+
@given_names = []
|
76
|
+
prediction['given_names'].each do |item|
|
77
|
+
@given_names.push(TextField.new(item, page_id))
|
78
|
+
end
|
79
|
+
@full_name = construct_full_name(page_id)
|
80
|
+
@mrz = construct_mrz(page_id)
|
81
|
+
check_mrz
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_s
|
85
|
+
given_names = @given_names.join(' ')
|
86
|
+
out_str = String.new
|
87
|
+
out_str << "\n:Full name: #{@full_name}".rstrip
|
88
|
+
out_str << "\n:Given names: #{given_names}".rstrip
|
89
|
+
out_str << "\n:Surname: #{@surname}".rstrip
|
90
|
+
out_str << "\n:Country: #{@country}".rstrip
|
91
|
+
out_str << "\n:ID Number: #{@id_number}".rstrip
|
92
|
+
out_str << "\n:Issuance date: #{@issuance_date}".rstrip
|
93
|
+
out_str << "\n:Birth date: #{@birth_date}".rstrip
|
94
|
+
out_str << "\n:Expiry date: #{@expiry_date}".rstrip
|
95
|
+
out_str << "\n:MRZ 1: #{@mrz1}".rstrip
|
96
|
+
out_str << "\n:MRZ 2: #{@mrz2}".rstrip
|
97
|
+
out_str << "\n:MRZ: #{@mrz}".rstrip
|
98
|
+
out_str[1..].to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [Boolean]
|
102
|
+
def expired?
|
103
|
+
return true unless @expiry_date.date_object
|
104
|
+
|
105
|
+
@expiry_date.date_object < Date.today
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def check_mrz
|
111
|
+
return if @mrz1.value.nil? || @mrz2.value.nil?
|
112
|
+
|
113
|
+
mrz = MRZ.parse([@mrz1.value, @mrz2.value])
|
114
|
+
checks = {
|
115
|
+
mrz_valid: valid_mrz?(mrz),
|
116
|
+
mrz_valid_birth_date: valid_birth_date?(mrz),
|
117
|
+
mrz_valid_expiry_date: valid_expiry_date?(mrz),
|
118
|
+
mrz_valid_id_number: valid_id_number?(mrz),
|
119
|
+
mrz_valid_surname: valid_surname?(mrz),
|
120
|
+
mrz_valid_country: valid_country?(mrz),
|
121
|
+
}
|
122
|
+
@checklist.merge!(checks)
|
123
|
+
end
|
124
|
+
|
125
|
+
def valid_mrz?(mrz)
|
126
|
+
check = mrz.valid?
|
127
|
+
@mrz.confidence = 1.0 if check
|
128
|
+
check
|
129
|
+
end
|
130
|
+
|
131
|
+
def valid_birth_date?(mrz)
|
132
|
+
check = mrz.valid_birth_date? && mrz.birth_date == @birth_date.date_object
|
133
|
+
@birth_date.confidence = 1.0 if check
|
134
|
+
check
|
135
|
+
end
|
136
|
+
|
137
|
+
def valid_expiry_date?(mrz)
|
138
|
+
check = mrz.valid_expiration_date? && mrz.expiration_date == @expiry_date.date_object
|
139
|
+
@expiry_date.confidence = 1.0 if check
|
140
|
+
check
|
141
|
+
end
|
142
|
+
|
143
|
+
def valid_id_number?(mrz)
|
144
|
+
check = mrz.valid_document_number? && mrz.document_number == @id_number.value
|
145
|
+
@id_number.confidence = 1.0 if check
|
146
|
+
check
|
147
|
+
end
|
148
|
+
|
149
|
+
def valid_surname?(mrz)
|
150
|
+
check = mrz.last_name == @surname.value
|
151
|
+
@surname.confidence = 1.0 if check
|
152
|
+
check
|
153
|
+
end
|
154
|
+
|
155
|
+
def valid_country?(mrz)
|
156
|
+
check = mrz.nationality == @country.value
|
157
|
+
@country.confidence = 1.0 if check
|
158
|
+
check
|
159
|
+
end
|
160
|
+
|
161
|
+
def construct_full_name(page_id)
|
162
|
+
return unless @surname.value &&
|
163
|
+
!@given_names.empty? &&
|
164
|
+
@given_names[0].value
|
165
|
+
|
166
|
+
full_name = {
|
167
|
+
'value' => "#{@given_names[0].value} #{@surname.value}",
|
168
|
+
'confidence' => TextField.array_confidence([@surname, @given_names[0]]),
|
169
|
+
}
|
170
|
+
TextField.new(full_name, page_id, reconstructed: true)
|
171
|
+
end
|
172
|
+
|
173
|
+
def construct_mrz(page_id)
|
174
|
+
return if @mrz1.value.nil? || @mrz2.value.nil?
|
175
|
+
|
176
|
+
mrz = {
|
177
|
+
'value' => @mrz1.value + @mrz2.value,
|
178
|
+
'confidence' => Mindee::TextField.array_confidence([@mrz1, @mrz2]),
|
179
|
+
}
|
180
|
+
TextField.new(mrz, page_id, reconstructed: true)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../common_fields'
|
4
|
+
require_relative '../base'
|
5
|
+
|
6
|
+
module Mindee
|
7
|
+
module Prediction
|
8
|
+
# Receipt document.
|
9
|
+
class ReceiptV4 < Prediction
|
10
|
+
# Where the purchase was made, the language, and the currency.
|
11
|
+
# @return [Mindee::Locale]
|
12
|
+
attr_reader :locale
|
13
|
+
# Total including taxes
|
14
|
+
# @return [Mindee::AmountField]
|
15
|
+
attr_reader :total_amount
|
16
|
+
# Total amount of the purchase excluding taxes.
|
17
|
+
# @return [Mindee::AmountField]
|
18
|
+
attr_reader :total_net
|
19
|
+
# Total tax amount of the purchase.
|
20
|
+
# @return [Mindee::AmountField]
|
21
|
+
attr_reader :total_tax
|
22
|
+
# The purchase date.
|
23
|
+
# @return [Mindee::DateField]
|
24
|
+
attr_reader :date
|
25
|
+
# The name of the supplier or merchant, as seen on the receipt.
|
26
|
+
# @return [Mindee::TextField]
|
27
|
+
attr_reader :supplier
|
28
|
+
# List of taxes detected on the receipt.
|
29
|
+
# @return [Array<Mindee::TaxField>]
|
30
|
+
attr_reader :taxes
|
31
|
+
# Time as seen on the receipt in HH:MM format.
|
32
|
+
# @return [Mindee::TextField]
|
33
|
+
attr_reader :time
|
34
|
+
# The receipt category among predefined classes.
|
35
|
+
# @return [Mindee::TextField]
|
36
|
+
attr_reader :category
|
37
|
+
# The receipt sub-category among predefined classes.
|
38
|
+
# @return [Mindee::TextField]
|
39
|
+
attr_reader :subcategory
|
40
|
+
# Whether the document is an expense receipt or a credit card receipt.
|
41
|
+
# @return [Mindee::TextField]
|
42
|
+
attr_reader :document_type
|
43
|
+
|
44
|
+
# @param prediction [Hash]
|
45
|
+
# @param page_id [Integer, nil]
|
46
|
+
def initialize(prediction, page_id)
|
47
|
+
super
|
48
|
+
@locale = Locale.new(prediction['locale'])
|
49
|
+
@total_amount = AmountField.new(prediction['total_amount'], page_id)
|
50
|
+
@total_net = AmountField.new(prediction['total_net'], page_id)
|
51
|
+
@total_tax = AmountField.new(prediction['total_tax'], page_id)
|
52
|
+
@tip = AmountField.new(prediction['tip'], page_id)
|
53
|
+
@date = DateField.new(prediction['date'], page_id)
|
54
|
+
@category = TextField.new(prediction['category'], page_id)
|
55
|
+
@subcategory = TextField.new(prediction['subcategory'], page_id)
|
56
|
+
@document_type = TextField.new(prediction['document_type'], page_id)
|
57
|
+
@supplier = TextField.new(prediction['supplier'], page_id)
|
58
|
+
@time = TextField.new(prediction['time'], page_id)
|
59
|
+
@taxes = []
|
60
|
+
prediction['taxes'].each do |item|
|
61
|
+
@taxes.push(TaxField.new(item, page_id))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
taxes = @taxes.join("\n ")
|
67
|
+
out_str = String.new
|
68
|
+
out_str << "\n:Locale: #{@locale}".rstrip
|
69
|
+
out_str << "\n:Date: #{@date}".rstrip
|
70
|
+
out_str << "\n:Category: #{@category}".rstrip
|
71
|
+
out_str << "\n:Subcategory: #{@subcategory}".rstrip
|
72
|
+
out_str << "\n:Document type: #{@document_type}".rstrip
|
73
|
+
out_str << "\n:Time: #{@time}".rstrip
|
74
|
+
out_str << "\n:Supplier name: #{@supplier}".rstrip
|
75
|
+
out_str << "\n:Taxes: #{taxes}".rstrip
|
76
|
+
out_str << "\n:Total net: #{@total_net}".rstrip
|
77
|
+
out_str << "\n:Total taxes: #{@total_tax}".rstrip
|
78
|
+
out_str << "\n:Tip: #{@tip}".rstrip
|
79
|
+
out_str << "\n:Total amount: #{@total_amount}".rstrip
|
80
|
+
out_str[1..].to_s
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../common_fields'
|
4
|
+
require_relative '../base'
|
5
|
+
|
6
|
+
module Mindee
|
7
|
+
module Prediction
|
8
|
+
# License plate prediction.
|
9
|
+
class ShippingContainerV1 < Prediction
|
10
|
+
# ISO 6346 code for container owner prefix + equipment identifier.
|
11
|
+
# @return [Array<Mindee::TextField>]
|
12
|
+
attr_reader :owner
|
13
|
+
# ISO 6346 code for container serial number (6+1 digits).
|
14
|
+
# @return [Array<Mindee::TextField>]
|
15
|
+
attr_reader :serial_number
|
16
|
+
# ISO 6346 code for container length, height and type.
|
17
|
+
# @return [Array<Mindee::TextField>]
|
18
|
+
attr_reader :size_type
|
19
|
+
|
20
|
+
# @param prediction [Hash]
|
21
|
+
# @param page_id [Integer, nil]
|
22
|
+
def initialize(prediction, page_id)
|
23
|
+
super
|
24
|
+
@owner = TextField.new(prediction['owner'], page_id)
|
25
|
+
@serial_number = TextField.new(prediction['serial_number'], page_id)
|
26
|
+
@size_type = TextField.new(prediction['size_type'], page_id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
out_str = String.new
|
31
|
+
out_str << "\n:Owner: #{@owner}".rstrip
|
32
|
+
out_str << "\n:Serial number: #{@serial_number}".rstrip
|
33
|
+
out_str << "\n:Size and type: #{@size_type}".rstrip
|
34
|
+
out_str[1..].to_s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../common_fields'
|
4
|
+
require_relative '../../base'
|
5
|
+
|
6
|
+
module Mindee
|
7
|
+
module Prediction
|
8
|
+
module US
|
9
|
+
# License plate prediction.
|
10
|
+
class BankCheckV1 < Prediction
|
11
|
+
# Payer's bank account number.
|
12
|
+
# @return [Array<Mindee::TextField>]
|
13
|
+
attr_reader :account_number
|
14
|
+
# Amount to be paid.
|
15
|
+
# @return [Array<Mindee::AmountField>]
|
16
|
+
attr_reader :amount
|
17
|
+
# The check number.
|
18
|
+
# @return [Mindee::TextField]
|
19
|
+
attr_reader :check_number
|
20
|
+
# Payer's bank account routing number.
|
21
|
+
# @return [Mindee::TextField]
|
22
|
+
attr_reader :routing_number
|
23
|
+
# Date the check was issued.
|
24
|
+
# @return [Mindee::DateField]
|
25
|
+
attr_reader :date
|
26
|
+
# The positions of the signatures on the image.
|
27
|
+
# @return [Array<Mindee::PositionField>]
|
28
|
+
attr_reader :signatures_positions
|
29
|
+
# Check's position in the image.
|
30
|
+
# @return [Mindee::PositionField]
|
31
|
+
attr_reader :check_position
|
32
|
+
# List of payees (full name or company name).
|
33
|
+
# @return [Array<Mindee::TextField>]
|
34
|
+
attr_reader :payees
|
35
|
+
|
36
|
+
# @param prediction [Hash]
|
37
|
+
# @param page_id [Integer, nil]
|
38
|
+
def initialize(prediction, page_id)
|
39
|
+
super
|
40
|
+
@account_number = TextField.new(prediction['account_number'], page_id)
|
41
|
+
@amount = AmountField.new(prediction['amount'], page_id)
|
42
|
+
@check_number = TextField.new(prediction['check_number'], page_id)
|
43
|
+
@date = DateField.new(prediction['date'], page_id)
|
44
|
+
@check_position = PositionField.new(prediction['check_position'], page_id)
|
45
|
+
@routing_number = TextField.new(prediction['routing_number'], page_id)
|
46
|
+
@signatures_positions = []
|
47
|
+
prediction['signatures_positions'].each do |item|
|
48
|
+
@signatures_positions.push(PositionField.new(item, page_id))
|
49
|
+
end
|
50
|
+
@payees = []
|
51
|
+
prediction['payees'].each do |item|
|
52
|
+
@payees.push(TextField.new(item, page_id))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_s
|
57
|
+
payees = @payees.map(&:value).join(', ')
|
58
|
+
out_str = String.new
|
59
|
+
out_str << "\n:Routing number: #{@routing_number}".rstrip
|
60
|
+
out_str << "\n:Account number: #{@account_number}".rstrip
|
61
|
+
out_str << "\n:Check number: #{@check_number}".rstrip
|
62
|
+
out_str << "\n:Date: #{@date}".rstrip
|
63
|
+
out_str << "\n:Amount: #{@amount}".rstrip
|
64
|
+
out_str << "\n:Payees: #{payees}".rstrip
|
65
|
+
out_str[1..].to_s
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'prediction/custom/custom_v1'
|
4
|
+
require_relative 'prediction/invoice/invoice_v4'
|
5
|
+
require_relative 'prediction/passport/passport_v1'
|
6
|
+
require_relative 'prediction/receipt/receipt_v4'
|
7
|
+
require_relative 'prediction/eu/license_plate/license_plate_v1'
|
8
|
+
require_relative 'prediction/shipping_container/shipping_container_v1'
|
9
|
+
require_relative 'prediction/us/bank_check/bank_check_v1'
|
10
|
+
require_relative 'prediction/fr/bank_account_details/bank_account_details_v1'
|
11
|
+
require_relative 'prediction/fr/carte_vitale/carte_vitale_v1'
|
12
|
+
require_relative 'prediction/fr/id_card/id_card_v1'
|
data/lib/mindee/version.rb
CHANGED
data/mindee.gemspec
CHANGED
@@ -31,9 +31,10 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
spec.add_runtime_dependency 'marcel', '~> 1.0.2'
|
33
33
|
spec.add_runtime_dependency 'mrz', '~> 0.2'
|
34
|
-
spec.add_runtime_dependency 'origamindee', '~> 3.
|
34
|
+
spec.add_runtime_dependency 'origamindee', '~> 3.1'
|
35
35
|
|
36
36
|
spec.add_development_dependency 'rake', '~> 12.3.1'
|
37
37
|
spec.add_development_dependency 'rspec', '~> 3.11'
|
38
38
|
spec.add_development_dependency 'rubocop', '~> 1.41'
|
39
|
+
spec.add_development_dependency 'yard', '0.9.28'
|
39
40
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mindee
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mindee, SA
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: marcel
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.1'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '3.
|
54
|
+
version: '3.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.41'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: yard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.9.28
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.9.28
|
97
111
|
description: Quickly and easily connect to Mindee's API services using Ruby.
|
98
112
|
email:
|
99
113
|
- devrel@mindee.co
|
@@ -107,6 +121,7 @@ files:
|
|
107
121
|
- ".gitignore"
|
108
122
|
- ".gitmodules"
|
109
123
|
- ".rubocop.yml"
|
124
|
+
- ".yardopts"
|
110
125
|
- CHANGELOG.md
|
111
126
|
- CODE_OF_CONDUCT.md
|
112
127
|
- CONTRIBUTING.md
|
@@ -116,30 +131,48 @@ files:
|
|
116
131
|
- Rakefile
|
117
132
|
- bin/console
|
118
133
|
- bin/mindee.rb
|
134
|
+
- docs/ruby-api-builder.md
|
135
|
+
- docs/ruby-getting-started.md
|
136
|
+
- docs/ruby-invoice-ocr.md
|
137
|
+
- docs/ruby-passport-ocr.md
|
138
|
+
- docs/ruby-receipt-ocr.md
|
119
139
|
- lib/mindee.rb
|
120
140
|
- lib/mindee/client.rb
|
121
141
|
- lib/mindee/document_config.rb
|
122
|
-
- lib/mindee/documents.rb
|
123
|
-
- lib/mindee/documents/base.rb
|
124
|
-
- lib/mindee/documents/custom.rb
|
125
|
-
- lib/mindee/documents/financial_doc.rb
|
126
|
-
- lib/mindee/documents/invoice.rb
|
127
|
-
- lib/mindee/documents/passport.rb
|
128
|
-
- lib/mindee/documents/receipt.rb
|
129
|
-
- lib/mindee/endpoint.rb
|
130
|
-
- lib/mindee/fields.rb
|
131
|
-
- lib/mindee/fields/amount.rb
|
132
|
-
- lib/mindee/fields/base.rb
|
133
|
-
- lib/mindee/fields/company_registration.rb
|
134
|
-
- lib/mindee/fields/custom_docs.rb
|
135
|
-
- lib/mindee/fields/datefield.rb
|
136
|
-
- lib/mindee/fields/locale.rb
|
137
|
-
- lib/mindee/fields/orientation.rb
|
138
|
-
- lib/mindee/fields/payment_details.rb
|
139
|
-
- lib/mindee/fields/tax.rb
|
140
142
|
- lib/mindee/geometry.rb
|
141
|
-
- lib/mindee/
|
142
|
-
- lib/mindee/
|
143
|
+
- lib/mindee/http/endpoint.rb
|
144
|
+
- lib/mindee/input.rb
|
145
|
+
- lib/mindee/input/pdf_processing.rb
|
146
|
+
- lib/mindee/input/sources.rb
|
147
|
+
- lib/mindee/parsing.rb
|
148
|
+
- lib/mindee/parsing/document.rb
|
149
|
+
- lib/mindee/parsing/error.rb
|
150
|
+
- lib/mindee/parsing/inference.rb
|
151
|
+
- lib/mindee/parsing/page.rb
|
152
|
+
- lib/mindee/parsing/prediction.rb
|
153
|
+
- lib/mindee/parsing/prediction/base.rb
|
154
|
+
- lib/mindee/parsing/prediction/common_fields.rb
|
155
|
+
- lib/mindee/parsing/prediction/common_fields/amount.rb
|
156
|
+
- lib/mindee/parsing/prediction/common_fields/base.rb
|
157
|
+
- lib/mindee/parsing/prediction/common_fields/company_registration.rb
|
158
|
+
- lib/mindee/parsing/prediction/common_fields/date.rb
|
159
|
+
- lib/mindee/parsing/prediction/common_fields/locale.rb
|
160
|
+
- lib/mindee/parsing/prediction/common_fields/payment_details.rb
|
161
|
+
- lib/mindee/parsing/prediction/common_fields/position.rb
|
162
|
+
- lib/mindee/parsing/prediction/common_fields/tax.rb
|
163
|
+
- lib/mindee/parsing/prediction/common_fields/text.rb
|
164
|
+
- lib/mindee/parsing/prediction/custom/custom_v1.rb
|
165
|
+
- lib/mindee/parsing/prediction/custom/fields.rb
|
166
|
+
- lib/mindee/parsing/prediction/eu/license_plate/license_plate_v1.rb
|
167
|
+
- lib/mindee/parsing/prediction/fr/bank_account_details/bank_account_details_v1.rb
|
168
|
+
- lib/mindee/parsing/prediction/fr/carte_vitale/carte_vitale_v1.rb
|
169
|
+
- lib/mindee/parsing/prediction/fr/id_card/id_card_v1.rb
|
170
|
+
- lib/mindee/parsing/prediction/invoice/invoice_line_item.rb
|
171
|
+
- lib/mindee/parsing/prediction/invoice/invoice_v4.rb
|
172
|
+
- lib/mindee/parsing/prediction/passport/passport_v1.rb
|
173
|
+
- lib/mindee/parsing/prediction/receipt/receipt_v4.rb
|
174
|
+
- lib/mindee/parsing/prediction/shipping_container/shipping_container_v1.rb
|
175
|
+
- lib/mindee/parsing/prediction/us/bank_check/bank_check_v1.rb
|
143
176
|
- lib/mindee/version.rb
|
144
177
|
- mindee.gemspec
|
145
178
|
homepage: https://github.com/mindee/mindee-api-ruby
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Mindee
|
4
|
-
# Base document object.
|
5
|
-
class Document
|
6
|
-
# document type
|
7
|
-
# @return [String]
|
8
|
-
attr_reader :document_type
|
9
|
-
# Validation checks for the document
|
10
|
-
# @return [Hash<Symbol, Boolean>]
|
11
|
-
attr_reader :checklist
|
12
|
-
# Original filename of the document
|
13
|
-
# @return [String, nil]
|
14
|
-
attr_reader :filename
|
15
|
-
# Detected MIME type of the document
|
16
|
-
# @return [String, nil]
|
17
|
-
attr_reader :file_mimetype
|
18
|
-
|
19
|
-
# @param input_file [Mindee::InputDocument, nil]
|
20
|
-
# @param document_type [String]
|
21
|
-
def initialize(document_type, input_file: nil)
|
22
|
-
@document_type = document_type
|
23
|
-
unless input_file.nil?
|
24
|
-
@filename = input_file.filename
|
25
|
-
@file_mimetype = input_file.file_mimetype
|
26
|
-
end
|
27
|
-
@checklist = {}
|
28
|
-
end
|
29
|
-
|
30
|
-
# @return [Boolean]
|
31
|
-
def all_checks
|
32
|
-
@checklist.all? { |_, value| value == true }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative '../fields'
|
4
|
-
require_relative 'base'
|
5
|
-
|
6
|
-
module Mindee
|
7
|
-
# Custom document object.
|
8
|
-
class CustomDocument < Document
|
9
|
-
# All value fields in the document
|
10
|
-
# @return [Hash<Symbol, Mindee::ListField>]
|
11
|
-
attr_reader :fields
|
12
|
-
# All classifications in the document
|
13
|
-
# @return [Hash<Symbol, Mindee::ClassificationField>]
|
14
|
-
attr_reader :classifications
|
15
|
-
|
16
|
-
# @param document_type [String]
|
17
|
-
# @param prediction [Hash]
|
18
|
-
# @param input_file [Mindee::InputDocument, nil]
|
19
|
-
# @param page_id [Integer, nil]
|
20
|
-
def initialize(document_type, prediction, input_file: nil, page_id: nil)
|
21
|
-
super(document_type, input_file: input_file)
|
22
|
-
@fields = {}
|
23
|
-
@classifications = {}
|
24
|
-
prediction.each do |field_name, field_prediction|
|
25
|
-
field_sym = field_name.to_sym
|
26
|
-
complete_field = set_field(field_sym, field_prediction, page_id)
|
27
|
-
|
28
|
-
# Create a dynamic accessor function for the field
|
29
|
-
singleton_class.module_eval { attr_accessor field_sym }
|
30
|
-
send("#{field_sym}=", complete_field)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def to_s
|
35
|
-
out_str = String.new
|
36
|
-
out_str << "----- #{@document_type} -----"
|
37
|
-
out_str << "\nFilename: #{@filename}".rstrip
|
38
|
-
@classifications.each do |name, info|
|
39
|
-
out_str << "\n#{name}: #{info}".rstrip
|
40
|
-
end
|
41
|
-
@fields.each do |name, info|
|
42
|
-
out_str << "\n#{name}: #{info}".rstrip
|
43
|
-
end
|
44
|
-
out_str << "\n----------------------"
|
45
|
-
out_str
|
46
|
-
end
|
47
|
-
|
48
|
-
private
|
49
|
-
|
50
|
-
# @param field_prediction [Hash]
|
51
|
-
def set_field(field_sym, field_prediction, page_id)
|
52
|
-
# Currently two types of fields possible in a custom API response:
|
53
|
-
# fields having a list of values, and classification fields.
|
54
|
-
# Here we use the fact that only value lists have the 'values' attribute.
|
55
|
-
|
56
|
-
if field_prediction.key? 'values'
|
57
|
-
@fields[field_sym] = ListField.new(field_prediction, page_id)
|
58
|
-
elsif field_prediction.key? 'value'
|
59
|
-
@classifications[field_sym] = ClassificationField.new(field_prediction)
|
60
|
-
else
|
61
|
-
throw 'Unknown API field type'
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|