blob: effa9f8964953f20ab81e8bcbfbcf53602484cc1 [file] [log] [blame]
Akrone51eaa32020-11-10 09:35:53 +01001"use strict";
2
Nils Diewald0e6992a2015-04-14 20:13:52 +00003define(['util'], function () {
Akronbf713fc2020-10-13 10:44:35 +02004
5 // TODO:
6 // - https://github.com/honza/140medley/blob/master/140medley.js
7 // - https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
8 // - https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
9 // - r.addEventListener("progress", updateProgress, false);
10 // - http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
11 // - http://stackoverflow.com/questions/6112744/load-javascript-on-demand
Nils Diewald58141332015-04-07 16:18:45 +000012
Leo Reppa6aba9a2021-01-23 20:16:43 +010013 // See https://flaviocopes.com/http-request-headers/ for a list of headers
14
Akron4c33c622018-11-12 13:43:27 +010015 KorAP.URL = KorAP.URL !== undefined ? KorAP.URL : '';
Nils Diewald4347ee92015-05-04 20:32:48 +000016 KorAP.API = KorAP.API || {};
Akronb89863a2018-11-13 16:43:59 +010017
Akronbf713fc2020-10-13 10:44:35 +020018 const legacySigle = new RegExp('^([^_]+)_([^\\.]+)\\.(.+?)$');
19
Akron48b1e4d2015-06-17 18:47:01 +020020 /**
21 * Retrieve information about a match
22 */
Nils Diewald4347ee92015-05-04 20:32:48 +000023 KorAP.API.getMatchInfo = function (match, param, cb) {
Nils Diewald58141332015-04-07 16:18:45 +000024
Nils Diewald4347ee92015-05-04 20:32:48 +000025 // match is a KorAP.Match object
Akronbf713fc2020-10-13 10:44:35 +020026 let url = KorAP.URL + '/corpus';
Akron0b489ad2018-02-02 16:49:32 +010027 /*
28 url += '/' + match.corpusID;
29 url += '/' + match.docID;
30 url += '/' + match.textID;
31 */
Akron19d97fe2016-09-06 20:47:05 +020032
Akron19d97fe2016-09-06 20:47:05 +020033 // This is for legacy support
Akronbf713fc2020-10-13 10:44:35 +020034 const legacy = legacySigle.exec(match.textSigle);
35 let docFragment = "";
Akron7f613e02016-11-07 02:50:44 +010036 if (legacy !== null && legacy[0]) {
Akronb89863a2018-11-13 16:43:59 +010037 docFragment = legacy[1] + '/' + legacy[2] + '/' + legacy[3];
Akron19d97fe2016-09-06 20:47:05 +020038 }
39 else {
Akronb89863a2018-11-13 16:43:59 +010040 docFragment = match.textSigle;
Akron19d97fe2016-09-06 20:47:05 +020041 }
Akronb89863a2018-11-13 16:43:59 +010042
43 docFragment += '/' + match.matchID;
Akron910828a2025-06-27 15:38:48 +020044 url += '/' + docFragment + '?';
Nils Diewald58141332015-04-07 16:18:45 +000045
Nils Diewald4347ee92015-05-04 20:32:48 +000046 // { spans: true, layer:x, foundry : y}
47 if (param['spans'] == true) {
Akron910828a2025-06-27 15:38:48 +020048 url += 'spans=true';
Akronb89863a2018-11-13 16:43:59 +010049 docFragment += ' +spans ';
50 if (param['foundry'] !== undefined) {
Akron515851a2017-05-02 12:53:17 +020051 url += '&foundry=' + param['foundry'];
Akronb89863a2018-11-13 16:43:59 +010052 docFragment += param['foundry'];
53 };
54 if (param['layer'] !== undefined) {
Akron515851a2017-05-02 12:53:17 +020055 url += '&layer=' + param['layer'];
Akronb89863a2018-11-13 16:43:59 +010056 docFragment += '/'+param['layer'];
57 }
Nils Diewald58141332015-04-07 16:18:45 +000058 }
Nils Diewald4347ee92015-05-04 20:32:48 +000059
60 // { spans : false, layer: [Array of KorAP.InfoLayer] }
61 else {
62 // TODO
Akronb89863a2018-11-13 16:43:59 +010063 docFragment += ' -spans';
Akron910828a2025-06-27 15:38:48 +020064 url += 'spans=false';
65 };
66
67 if (KorAP.ResponsePipe != null)
68 url += '&response-pipe=' + KorAP.ResponsePipe.toString();
Nils Diewald4347ee92015-05-04 20:32:48 +000069
Akronb89863a2018-11-13 16:43:59 +010070 KorAP.API.getJSON(url, cb, "MatchInfo: " + docFragment);
Nils Diewald58141332015-04-07 16:18:45 +000071 };
Nils Diewald4347ee92015-05-04 20:32:48 +000072
Akron0b489ad2018-02-02 16:49:32 +010073
Akron48b1e4d2015-06-17 18:47:01 +020074 /**
Akron0ad7cd22018-02-08 18:03:06 +010075 * Retrieve information about a document.
76 */
77 KorAP.API.getTextInfo = function (doc, param, cb) {
78
79 // doc is a KorAP.Match object
Akronbf713fc2020-10-13 10:44:35 +020080 let url = KorAP.URL + '/corpus' + '/' + doc.textSigle;
Akron0ad7cd22018-02-08 18:03:06 +010081
82 if (param['fields'] !== undefined) {
83 url += '?fields='; // TODO!
84 }
85 else {
Akron4bbd8b32018-03-06 19:19:44 +010086 url += '?fields=@all'; // TODO: Maybe '*'?
Akron910828a2025-06-27 15:38:48 +020087 };
Akronbf713fc2020-10-13 10:44:35 +020088
Akron910828a2025-06-27 15:38:48 +020089 if (KorAP.ResponsePipe != null)
90 url += '&response-pipe=' + KorAP.ResponsePipe.toString();
91
92
Akronb89863a2018-11-13 16:43:59 +010093 KorAP.API.getJSON(url, cb, "TextInfo: " + doc.textSigle);
Akron0ad7cd22018-02-08 18:03:06 +010094 };
95
96
97 /**
Akroncd42a142019-07-12 18:55:37 +020098 * Retrieve information about virtual corpora
Akron48b1e4d2015-06-17 18:47:01 +020099 */
100 KorAP.API.getCollections = function (cb) {
Akronb89863a2018-11-13 16:43:59 +0100101 KorAP.API.getJSON(KorAP.URL + '/collection', cb, "CorpusInfo");
Akron48b1e4d2015-06-17 18:47:01 +0200102 };
103
hebasta0ee50802018-06-20 10:24:45 +0200104
105 /**
106 * Retrieve information about corpus statistic
107 *
108 * Example URL: /corpus?cq=availability+%3D+%2FCC-BY.*%2F+%26+textClass+%3D+%22kultur%22
109 *
Leo Reppa6aba9a2021-01-23 20:16:43 +0100110 * @param cq corpus query (formerly collectionQuery)
hebasta0ee50802018-06-20 10:24:45 +0200111 *
112 * Adress the MOJO-Endpoint for example with
113 * http://localhost:3000/corpus?cq=availability+%3D+%2FCC-BY.*%2F+%26+textClass+%3D+%22kultur%22
114 */
115 KorAP.API.getCorpStat = function (cq, cb){
Akronbf713fc2020-10-13 10:44:35 +0200116 let url = KorAP.URL + "/corpus?cq=" + encodeURIComponent(cq);
Akronb89863a2018-11-13 16:43:59 +0100117 KorAP.API.getJSON(url, cb, "CorpusInfo: " + cq);
hebasta0ee50802018-06-20 10:24:45 +0200118 };
Akron8dda1c62021-01-20 10:27:32 +0100119
120
121 /**
122 * Retrieve a list of all plugin objects to
123 * establish in the frontend.
124 */
125 KorAP.API.getPluginList = function (url, cb) {
126 KorAP.API.getJSON(url, cb, "Plugin-List")
127 };
Akronbf713fc2020-10-13 10:44:35 +0200128
hebasta4ba496a2018-06-05 15:56:01 +0200129 /**
Leo Reppa6aba9a2021-01-23 20:16:43 +0100130 * General function to communicate JS Objects with the server
131 *
132 * @param {HTTMLRequestType} requestType Should be "GET", "PUT", "POST" or "DELETE"
133 * @param {String} url The url that specifies where the JSON file is ("GET"), will be ("PUT" and "POST") or will have been ("DELETE")
134 * @param {String} title How to store this request in the logs
135 * @param {JSObj} jsObj For "PUT" and "POST". The JS Object that is getting transfered. This function stringifies it.
136 * @param {function} returnValueCB For "GET". The callback function that receives the retrieved JS object (already parsed) as a parameter, or undefined if none is eligible
137 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
138 */
139 function _actionJSON (requestType, url, title, jsObj, returnValueCB, errorCB) {
Akronbf713fc2020-10-13 10:44:35 +0200140 const req = new XMLHttpRequest();
Leo Reppa6aba9a2021-01-23 20:16:43 +0100141 req.open(requestType, url, true);
142 // Dispatch global "window" event. See Kalamar::Plugin::Piwik
Akronbf713fc2020-10-13 10:44:35 +0200143 const reqE = new CustomEvent('korapRequest', {
Akron4c33c622018-11-12 13:43:27 +0100144 bubbles : false,
Akronb89863a2018-11-13 16:43:59 +0100145 detail: {
146 "url" : url,
147 "title" : title
148 }
Akron4c33c622018-11-12 13:43:27 +0100149 });
150 window.dispatchEvent(reqE);
151
Nils Diewald4347ee92015-05-04 20:32:48 +0000152 req.setRequestHeader("Accept", "application/json");
Leo Reppa6aba9a2021-01-23 20:16:43 +0100153 req.setRequestHeader("Content-Type", "application/json");
154 req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
Leo Repp57997402021-08-18 16:37:52 +0200155 //req.setRequestHeader('Origin',"API");
Nils Diewald4347ee92015-05-04 20:32:48 +0000156 req.onreadystatechange = function () {
157 /*
Akron0b489ad2018-02-02 16:49:32 +0100158 States:
159 0 - unsent (prior to open)
160 1 - opened (prior to send)
161 2 - headers received
162 3 - loading (responseText has partial data)
163 4 - done
Nils Diewald4347ee92015-05-04 20:32:48 +0000164 */
165 if (this.readyState == 4) {
Akron515851a2017-05-02 12:53:17 +0200166
Leo Reppa6aba9a2021-01-23 20:16:43 +0100167 if (requestType === "GET") { //GET
168 let retJSObj;
169 try {
170 retJSObj = JSON.parse(this.responseText);
171 }
172 catch (e) {
173 KorAP.log(0, e);
174 console.log(e);
175 returnValueCB(undefined);
176 return;
177 };
178
Akrone71bd6d2024-06-11 15:47:39 +0200179 if (retJSObj !== undefined) {
180 if (retJSObj["errors"] !== undefined) {
181 retJSObj["errors"].forEach(
182 e => KorAP.log(e[0], e[1] || "Unknown")
183 );
184 } else if (retJSObj["warnings"] !== undefined) {
185 retJSObj["warnings"].forEach(
186 e => KorAP.log(e[0], e[1] || "Unknown", null, 'warn')
187 );
188 }
Leo Reppa6aba9a2021-01-23 20:16:43 +0100189 }
190
191 else if (this.status !== 200) {
192 KorAP.log(this.status, this.statusText, "Remote service error (XMLHttpRequest) under URL: " + url);
193 };
194
195 if (this.status === 200) {
196 returnValueCB(retJSObj);
197 }
198
199 else {
200 returnValueCB(undefined);
201 };
202
203 } else { // PUT, POST, DELETE
204 if (this.status >= 300 || this.status < 200) { //Error
205 KorAP.log(this.status, this.statusText, "Remote service error (XMLHttpRequest) under URL: " + url);
206 };
Akronb5d05d72018-02-12 15:09:12 +0100207 };
Leo Reppa6aba9a2021-01-23 20:16:43 +0100208 // Call the callback function (no matter requestType) if one is given.
209 if (typeof(errorCB) === "function"){
210 errorCB({
211 "status" : this.status,
212 "statusText" : this.statusText
213 });
214 };
215 };
Nils Diewald4347ee92015-05-04 20:32:48 +0000216 };
Akronbf713fc2020-10-13 10:44:35 +0200217
Leo Reppa6aba9a2021-01-23 20:16:43 +0100218 /*Set a value for .timeout to use this functionality */
219 //req.ontimeout = function () {
220 // KorAP.log(0, 'Request Timeout');
221 //};
222 if (requestType === "POST" || requestType === "PUT") {
223 req.send(JSON.stringify(jsObj));
224 } else { //GET, DELETE
225 req.send();
Nils Diewald4347ee92015-05-04 20:32:48 +0000226 };
Leo Reppa6aba9a2021-01-23 20:16:43 +0100227 };
228
229 /**
230 * General method to get JSON information.
231 *
232 * @param {String} url The url at which the JSON File will be located
233 * @param {function} returnValueCB The callback function that receives the retrieved JS object (already parsed) as a parameter, or undefined if none is eligible
234 * @param {String} title How to store this request in the logs
235 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
236 */
237 KorAP.API.getJSON = function (url, returnValueCB, title, errorCB) {
238 _actionJSON("GET", url, title, undefined, returnValueCB, errorCB);
239 };
240
241 /**
242 * General method to put JSON information.
243 *
244 * @param {String} url The url at which the JSON File will be located
245 * @param {JSObj} jsObj The JS object that is getting transfered. This will be stringified
246 * @param {String} title How to store this request in the logs
247 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
248 */
249 KorAP.API.putJSON = function (url, jsObj, title, errorCB) {
250 _actionJSON("PUT", url, title, jsObj, undefined, errorCB);
251 };
252
253 /**
254 * General method to post JSON information.
255 *
256 * @param {String} url The url at which the JSON File will be located
257 * @param {JSObj} jsObj The JS object that is getting transfered. This will be stringified
258 * @param {String} title How to store this request in the logs
259 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
260 */
261 KorAP.API.postJSON = function (url, jsObj, title, errorCB) {
262 _actionJSON("POST", url, title, jsObj, undefined, errorCB);
263 };
264
265 /**
266 * General method to delete a file at a specific URL
267 *
268 * @param {String} url The url at which the to be deleted file is located
269 * @param {String} title How to store this request in the logs
270 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
271 */
272 KorAP.API.deleteJSON = function (url, title, errorCB) {
273 _actionJSON("DELETE", url, title, undefined, undefined, errorCB);
274 };
275
276
277 // Stored query related functions
278
279 /**
280 * Retrieve saved list of queries
281 *
282 * @param {function} returnValueCB The callback function that receives the JS object Listof queries, already parsed
283 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
284 */
285 KorAP.API.getQueryList = function (returnValueCB, errorCB){
286 KorAP.API.getJSON(KorAP.URL + "/query/", returnValueCB, "getSavedQueryList", errorCB);
287 };
288
289 /**
290 * Retrieve specific saved query by query name
291 *
292 * @param {String} qn The name of the query to be retrieved. Must be a string
293 * @param {function} returnValueCB The callback function that receives the query JS object Object, already parsed
294 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
295 */
296 KorAP.API.getQuery = function (qn, returnValueCB, errorCB){
297 KorAP.API.getJSON(KorAP.URL + "/query/" + qn, returnValueCB, "getSavedQuery of name "+ qn, errorCB);
298 };
299
300 /**
301 * Put new query by query name
302 *
303 * @param {String} qn The name of the new query
304 * @param {JSObj} jsObj The query. This will be stringified
305 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
306 */
307 KorAP.API.putQuery = function (qn, jsObj, errorCB){
308 KorAP.API.putJSON(KorAP.URL + "/query/" + qn, jsObj, "putQuery of name "+ qn, errorCB);
309 };
310
311 /**
312 * Post new query by query name
313 *
314 * @param {String} qn The name of the new query
315 * @param {JSObj} jsObj The query. This will be stringified
316 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
317 */
318 KorAP.API.postQuery = function (qn, jsObj, errorCB){
319 KorAP.API.postJSON(KorAP.URL + "/query/" + qn, jsObj, "postQuery of name "+ qn, errorCB);
320 };
321
322 /**
323 * delete query by query name
324 *
325 * @param {String} qn The name of the to be deleted query
326 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
327 */
328 KorAP.API.deleteQuery = function (qn, errorCB){
329 KorAP.API.deleteJSON(KorAP.URL + "/query/" + qn, "deleteQuery of name "+ qn, errorCB);
330 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000331});