1 | /**
|
---|
2 | * @file Defines components that are used to interact with the OCR servlet.
|
---|
3 | * @author Carl Stephens
|
---|
4 | * @module
|
---|
5 | */
|
---|
6 |
|
---|
7 | import { log } from "./Util"
|
---|
8 |
|
---|
9 | export class OcrError extends Error
|
---|
10 | {
|
---|
11 | /**
|
---|
12 | * Initializes a new instance of the {@link OcrError} object.
|
---|
13 | *
|
---|
14 | * @param {Number | undefined} statusCode The HTTP status code of the error.
|
---|
15 | * @param {String | undefined} message The status message.
|
---|
16 | * @param {String | null} fileName The file on which the OCR process failed.
|
---|
17 | */
|
---|
18 | constructor(message = undefined, fileName = null, statusCode = -1)
|
---|
19 | {
|
---|
20 | super(message);
|
---|
21 |
|
---|
22 | /** @type {String | null} The name of the file that the OCR error occured on. */
|
---|
23 | this.fileName = fileName;
|
---|
24 |
|
---|
25 | /** @type {Number | undefined} The status code returned by the API when the error was generated. */
|
---|
26 | this.statusCode = statusCode;
|
---|
27 | }
|
---|
28 | }
|
---|
29 |
|
---|
30 | export class OcrOptions
|
---|
31 | {
|
---|
32 | /**
|
---|
33 | * Initializes a new instance of the {@link OcrOptions} object.
|
---|
34 | * @param {Boolean} layoutDetection Whether or not to enable automatic layout detection.
|
---|
35 | */
|
---|
36 | constructor(layoutDetection)
|
---|
37 | {
|
---|
38 | this.layoutDetection = layoutDetection;
|
---|
39 | }
|
---|
40 | }
|
---|
41 |
|
---|
42 | /**
|
---|
43 | * A service that performs requests to the OCR API.
|
---|
44 | */
|
---|
45 | export default class OcrService
|
---|
46 | {
|
---|
47 | constructor()
|
---|
48 | {
|
---|
49 | /** @type {String} The URL to which query POST requests should be made. */
|
---|
50 | if (process.env.NODE_ENV !== "production") {
|
---|
51 | this.queryUrl = "//localhost:8383/gs3-atea-ocr/tesseract";
|
---|
52 | }
|
---|
53 | else {
|
---|
54 | this.queryUrl = "/gs3-atea-ocr/tesseract";
|
---|
55 | }
|
---|
56 | }
|
---|
57 |
|
---|
58 | // TODO: Needs to allow blobs, and take file name
|
---|
59 | /**
|
---|
60 | * Makes an OCR request.
|
---|
61 | * @param {{image: File, options: OcrOptions}[]} images The image set to perform OCR on.
|
---|
62 | * @returns {Promise<{key: String, fileName: String, text: String}[]>} A JSON list of the recognised text.
|
---|
63 | */
|
---|
64 | async run(images)
|
---|
65 | {
|
---|
66 | const queryUrl = this.queryUrl;
|
---|
67 |
|
---|
68 | try
|
---|
69 | {
|
---|
70 | const options = {};
|
---|
71 | const formData = new FormData();
|
---|
72 |
|
---|
73 | for (let i = 0; i < images.length; i++)
|
---|
74 | {
|
---|
75 | const element = images[i];
|
---|
76 | const name = i + element.image.name;
|
---|
77 |
|
---|
78 | options[name] = element.options;
|
---|
79 | formData.append(name, element.image, element.image.name);
|
---|
80 | }
|
---|
81 |
|
---|
82 | formData.append("options", JSON.stringify(options));
|
---|
83 |
|
---|
84 | const response = await fetch(
|
---|
85 | queryUrl,
|
---|
86 | {
|
---|
87 | method: "POST",
|
---|
88 | body: formData
|
---|
89 | }
|
---|
90 | );
|
---|
91 |
|
---|
92 | if (!response.ok)
|
---|
93 | {
|
---|
94 | log(`OCR failed with status ${response.status} and message ${response.statusText}`, "error");
|
---|
95 | throw new OcrError(response.statusText, null, response.status);
|
---|
96 | }
|
---|
97 |
|
---|
98 | return await response.json();
|
---|
99 | }
|
---|
100 | catch (e)
|
---|
101 | {
|
---|
102 | log(`OCR failed with reason ${e}`, "error");
|
---|
103 | throw new OcrError("Unknown", null, null)
|
---|
104 | }
|
---|
105 | }
|
---|
106 | }
|
---|