blob: 3b3b82133090cb89650c071994fb10b62d9416d1 [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;
44 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) {
48 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';
Nils Diewald4347ee92015-05-04 20:32:48 +000064 url += '?spans=false';
65 }
66
Akronb89863a2018-11-13 16:43:59 +010067 KorAP.API.getJSON(url, cb, "MatchInfo: " + docFragment);
Nils Diewald58141332015-04-07 16:18:45 +000068 };
Nils Diewald4347ee92015-05-04 20:32:48 +000069
Akron0b489ad2018-02-02 16:49:32 +010070
Akron48b1e4d2015-06-17 18:47:01 +020071 /**
Akron0ad7cd22018-02-08 18:03:06 +010072 * Retrieve information about a document.
73 */
74 KorAP.API.getTextInfo = function (doc, param, cb) {
75
76 // doc is a KorAP.Match object
Akronbf713fc2020-10-13 10:44:35 +020077 let url = KorAP.URL + '/corpus' + '/' + doc.textSigle;
Akron0ad7cd22018-02-08 18:03:06 +010078
79 if (param['fields'] !== undefined) {
80 url += '?fields='; // TODO!
81 }
82 else {
Akron4bbd8b32018-03-06 19:19:44 +010083 url += '?fields=@all'; // TODO: Maybe '*'?
Akron0ad7cd22018-02-08 18:03:06 +010084 }
Akronbf713fc2020-10-13 10:44:35 +020085
Akronb89863a2018-11-13 16:43:59 +010086 KorAP.API.getJSON(url, cb, "TextInfo: " + doc.textSigle);
Akron0ad7cd22018-02-08 18:03:06 +010087 };
88
89
90 /**
Akroncd42a142019-07-12 18:55:37 +020091 * Retrieve information about virtual corpora
Akron48b1e4d2015-06-17 18:47:01 +020092 */
93 KorAP.API.getCollections = function (cb) {
Akronb89863a2018-11-13 16:43:59 +010094 KorAP.API.getJSON(KorAP.URL + '/collection', cb, "CorpusInfo");
Akron48b1e4d2015-06-17 18:47:01 +020095 };
96
hebasta0ee50802018-06-20 10:24:45 +020097
98 /**
99 * Retrieve information about corpus statistic
100 *
101 * Example URL: /corpus?cq=availability+%3D+%2FCC-BY.*%2F+%26+textClass+%3D+%22kultur%22
102 *
Leo Reppa6aba9a2021-01-23 20:16:43 +0100103 * @param cq corpus query (formerly collectionQuery)
hebasta0ee50802018-06-20 10:24:45 +0200104 *
105 * Adress the MOJO-Endpoint for example with
106 * http://localhost:3000/corpus?cq=availability+%3D+%2FCC-BY.*%2F+%26+textClass+%3D+%22kultur%22
107 */
108 KorAP.API.getCorpStat = function (cq, cb){
Akronbf713fc2020-10-13 10:44:35 +0200109 let url = KorAP.URL + "/corpus?cq=" + encodeURIComponent(cq);
Akronb89863a2018-11-13 16:43:59 +0100110 KorAP.API.getJSON(url, cb, "CorpusInfo: " + cq);
hebasta0ee50802018-06-20 10:24:45 +0200111 };
Akron8dda1c62021-01-20 10:27:32 +0100112
113
114 /**
115 * Retrieve a list of all plugin objects to
116 * establish in the frontend.
117 */
118 KorAP.API.getPluginList = function (url, cb) {
119 KorAP.API.getJSON(url, cb, "Plugin-List")
120 };
Akronbf713fc2020-10-13 10:44:35 +0200121
hebasta4ba496a2018-06-05 15:56:01 +0200122 /**
Leo Reppa6aba9a2021-01-23 20:16:43 +0100123 * General function to communicate JS Objects with the server
124 *
125 * @param {HTTMLRequestType} requestType Should be "GET", "PUT", "POST" or "DELETE"
126 * @param {String} url The url that specifies where the JSON file is ("GET"), will be ("PUT" and "POST") or will have been ("DELETE")
127 * @param {String} title How to store this request in the logs
128 * @param {JSObj} jsObj For "PUT" and "POST". The JS Object that is getting transfered. This function stringifies it.
129 * @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
130 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
131 */
132 function _actionJSON (requestType, url, title, jsObj, returnValueCB, errorCB) {
Akronbf713fc2020-10-13 10:44:35 +0200133 const req = new XMLHttpRequest();
Leo Reppa6aba9a2021-01-23 20:16:43 +0100134 req.open(requestType, url, true);
135 // Dispatch global "window" event. See Kalamar::Plugin::Piwik
Akronbf713fc2020-10-13 10:44:35 +0200136 const reqE = new CustomEvent('korapRequest', {
Akron4c33c622018-11-12 13:43:27 +0100137 bubbles : false,
Akronb89863a2018-11-13 16:43:59 +0100138 detail: {
139 "url" : url,
140 "title" : title
141 }
Akron4c33c622018-11-12 13:43:27 +0100142 });
143 window.dispatchEvent(reqE);
144
Nils Diewald4347ee92015-05-04 20:32:48 +0000145 req.setRequestHeader("Accept", "application/json");
Leo Reppa6aba9a2021-01-23 20:16:43 +0100146 req.setRequestHeader("Content-Type", "application/json");
147 req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
Leo Repp57997402021-08-18 16:37:52 +0200148 //req.setRequestHeader('Origin',"API");
Nils Diewald4347ee92015-05-04 20:32:48 +0000149 req.onreadystatechange = function () {
150 /*
Akron0b489ad2018-02-02 16:49:32 +0100151 States:
152 0 - unsent (prior to open)
153 1 - opened (prior to send)
154 2 - headers received
155 3 - loading (responseText has partial data)
156 4 - done
Nils Diewald4347ee92015-05-04 20:32:48 +0000157 */
158 if (this.readyState == 4) {
Akron515851a2017-05-02 12:53:17 +0200159
Leo Reppa6aba9a2021-01-23 20:16:43 +0100160 if (requestType === "GET") { //GET
161 let retJSObj;
162 try {
163 retJSObj = JSON.parse(this.responseText);
164 }
165 catch (e) {
166 KorAP.log(0, e);
167 console.log(e);
168 returnValueCB(undefined);
169 return;
170 };
171
Akrone71bd6d2024-06-11 15:47:39 +0200172 if (retJSObj !== undefined) {
173 if (retJSObj["errors"] !== undefined) {
174 retJSObj["errors"].forEach(
175 e => KorAP.log(e[0], e[1] || "Unknown")
176 );
177 } else if (retJSObj["warnings"] !== undefined) {
178 retJSObj["warnings"].forEach(
179 e => KorAP.log(e[0], e[1] || "Unknown", null, 'warn')
180 );
181 }
Leo Reppa6aba9a2021-01-23 20:16:43 +0100182 }
183
184 else if (this.status !== 200) {
185 KorAP.log(this.status, this.statusText, "Remote service error (XMLHttpRequest) under URL: " + url);
186 };
187
188 if (this.status === 200) {
189 returnValueCB(retJSObj);
190 }
191
192 else {
193 returnValueCB(undefined);
194 };
195
196 } else { // PUT, POST, DELETE
197 if (this.status >= 300 || this.status < 200) { //Error
198 KorAP.log(this.status, this.statusText, "Remote service error (XMLHttpRequest) under URL: " + url);
199 };
Akronb5d05d72018-02-12 15:09:12 +0100200 };
Leo Reppa6aba9a2021-01-23 20:16:43 +0100201 // Call the callback function (no matter requestType) if one is given.
202 if (typeof(errorCB) === "function"){
203 errorCB({
204 "status" : this.status,
205 "statusText" : this.statusText
206 });
207 };
208 };
Nils Diewald4347ee92015-05-04 20:32:48 +0000209 };
Akronbf713fc2020-10-13 10:44:35 +0200210
Leo Reppa6aba9a2021-01-23 20:16:43 +0100211 /*Set a value for .timeout to use this functionality */
212 //req.ontimeout = function () {
213 // KorAP.log(0, 'Request Timeout');
214 //};
215 if (requestType === "POST" || requestType === "PUT") {
216 req.send(JSON.stringify(jsObj));
217 } else { //GET, DELETE
218 req.send();
Nils Diewald4347ee92015-05-04 20:32:48 +0000219 };
Leo Reppa6aba9a2021-01-23 20:16:43 +0100220 };
221
222 /**
223 * General method to get JSON information.
224 *
225 * @param {String} url The url at which the JSON File will be located
226 * @param {function} returnValueCB The callback function that receives the retrieved JS object (already parsed) as a parameter, or undefined if none is eligible
227 * @param {String} title How to store this request in the logs
228 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
229 */
230 KorAP.API.getJSON = function (url, returnValueCB, title, errorCB) {
231 _actionJSON("GET", url, title, undefined, returnValueCB, errorCB);
232 };
233
234 /**
235 * General method to put JSON information.
236 *
237 * @param {String} url The url at which the JSON File will be located
238 * @param {JSObj} jsObj The JS object that is getting transfered. This will be stringified
239 * @param {String} title How to store this request in the logs
240 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
241 */
242 KorAP.API.putJSON = function (url, jsObj, title, errorCB) {
243 _actionJSON("PUT", url, title, jsObj, undefined, errorCB);
244 };
245
246 /**
247 * General method to post JSON information.
248 *
249 * @param {String} url The url at which the JSON File will be located
250 * @param {JSObj} jsObj The JS object that is getting transfered. This will be stringified
251 * @param {String} title How to store this request in the logs
252 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
253 */
254 KorAP.API.postJSON = function (url, jsObj, title, errorCB) {
255 _actionJSON("POST", url, title, jsObj, undefined, errorCB);
256 };
257
258 /**
259 * General method to delete a file at a specific URL
260 *
261 * @param {String} url The url at which the to be deleted file is located
262 * @param {String} title How to store this request in the logs
263 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
264 */
265 KorAP.API.deleteJSON = function (url, title, errorCB) {
266 _actionJSON("DELETE", url, title, undefined, undefined, errorCB);
267 };
268
269
270 // Stored query related functions
271
272 /**
273 * Retrieve saved list of queries
274 *
275 * @param {function} returnValueCB The callback function that receives the JS object Listof queries, already parsed
276 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
277 */
278 KorAP.API.getQueryList = function (returnValueCB, errorCB){
279 KorAP.API.getJSON(KorAP.URL + "/query/", returnValueCB, "getSavedQueryList", errorCB);
280 };
281
282 /**
283 * Retrieve specific saved query by query name
284 *
285 * @param {String} qn The name of the query to be retrieved. Must be a string
286 * @param {function} returnValueCB The callback function that receives the query JS object Object, already parsed
287 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
288 */
289 KorAP.API.getQuery = function (qn, returnValueCB, errorCB){
290 KorAP.API.getJSON(KorAP.URL + "/query/" + qn, returnValueCB, "getSavedQuery of name "+ qn, errorCB);
291 };
292
293 /**
294 * Put new query by query name
295 *
296 * @param {String} qn The name of the new query
297 * @param {JSObj} jsObj The query. This will be stringified
298 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
299 */
300 KorAP.API.putQuery = function (qn, jsObj, errorCB){
301 KorAP.API.putJSON(KorAP.URL + "/query/" + qn, jsObj, "putQuery of name "+ qn, errorCB);
302 };
303
304 /**
305 * Post new query by query name
306 *
307 * @param {String} qn The name of the new query
308 * @param {JSObj} jsObj The query. This will be stringified
309 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
310 */
311 KorAP.API.postQuery = function (qn, jsObj, errorCB){
312 KorAP.API.postJSON(KorAP.URL + "/query/" + qn, jsObj, "postQuery of name "+ qn, errorCB);
313 };
314
315 /**
316 * delete query by query name
317 *
318 * @param {String} qn The name of the to be deleted query
319 * @param {function} errorCB Optional. Callback function for error handling, receives JS object with status and statusText attribute
320 */
321 KorAP.API.deleteQuery = function (qn, errorCB){
322 KorAP.API.deleteJSON(KorAP.URL + "/query/" + qn, "deleteQuery of name "+ qn, errorCB);
323 };
Nils Diewald0e6992a2015-04-14 20:13:52 +0000324});