Project

General

Profile

1
import {Injectable, OnDestroy} from '@angular/core';
2
import {HttpClient} from "@angular/common/http";
3
import {SearchResult} from '../utils/entities/searchResult';
4
import {RefineResultsUtils} from './servicesUtils/refineResults.class';
5
import {Dates, DOI, StringUtils} from '../utils/string-utils.class';
6
import {ParsingFunctions} from '../landingPages/landing-utils/parsingFunctions.class';
7
import {EnvProperties} from '../utils/properties/env-properties';
8
import {map} from "rxjs/operators";
9
import {properties} from "../../../environments/environment";
10

    
11

    
12
@Injectable()
13
export class SearchResearchResultsService {
14
  private sizeOfDescription: number = 270;
15
  public parsingFunctions: ParsingFunctions = new ParsingFunctions();
16
  
17
  constructor(private http: HttpClient) {
18
  }
19
  
20
  
21
  search(resultType: string, params: string, refineParams: string, page: number, size: number, sortBy: string, refineFields: string[], properties: EnvProperties): any {
22
    let link = properties.searchAPIURLLAst + this.getEntityName(resultType, true);
23
    
24
    let url = link + "?";
25
    if (params != null && params != '') {
26
      url += params;
27
    }
28
    if (refineParams != null && refineParams != '') {
29
      url += refineParams;
30
    }
31
    if (sortBy) {
32
      url += "&sortBy=" + sortBy;
33
    }
34
    url += "&page=" + (page - 1) + "&size=" + size + "&format=json";
35
    
36
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
37
      .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
38
  }
39
  
40
  searchById(resultType: string, id: string, properties: EnvProperties): any {
41
    let url = properties.searchAPIURLLAst + this.getEntityName(resultType, true) + "/" + id + "?format=json";
42
    
43
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
44
      .pipe(map(res => this.parseResults(resultType, res, properties)));
45
  }
46
  
47
  searchAggregators(resultType: string, id: string, params: string, refineParams: string, page: number, size: number, properties: EnvProperties): any {
48
    let link = properties.searchAPIURLLAst + this.getEntityName(resultType, true);
49
    
50
    let url = link + "?" + "&format=json";
51
    if (params != null && params != '') {
52
      url += params;
53
    }
54
    if (refineParams != null && refineParams != '') {
55
      url += refineParams;
56
    }
57
    url += "&page=" + (page - 1) + "&size=" + size;
58
    
59
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
60
      .pipe(map(res => this.parseRefineResults(id, res['refineResults'])));
61
  }
62
  
63
  searchByListOfDOI(resultType: string, DOIs: string[], refineParams: string, page: number, size: number, refineFields: string[], properties: EnvProperties): any {
64
    let link = properties.searchAPIURLLAst + this.getEntityName(resultType, true);
65
    
66
    let url = link + "?" + "&format=json&";
67
    var doisParams = "";
68
    
69
    for (var i = 0; i < DOIs.length; i++) {
70
      doisParams += (doisParams.length > 0 ? "&" : "") + 'doi="' + DOIs[i] + '"';
71
    }
72
    if (doisParams.length > 0) {
73
      url += "&" + doisParams;
74
      
75
    }
76
    if (refineParams != null && refineParams != '') {
77
      url += refineParams;
78
    }
79
    url += "&page=" + (page - 1) + "&size=" + size;
80
    
81
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
82
      .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
83
  }
84
  
85
  advancedSearch(resultType: string, params: string, page: number, size: number, sortBy: string, properties: EnvProperties, refineParams: string = null, refineFields: string[] = null, refineQuery: string = null): any {
86
    let url = properties.searchResourcesAPIURL;
87
    var basicQuery = "(oaftype exact result) and (resulttypeid exact " + this.getEntityName(resultType, false) + ") ";
88
    url += "?query=";
89
    if (params != null && params != '') {
90
      url += " ( " + basicQuery + " ) " + " and (" + params + ")";
91
    } else {
92
      url += " ( " + basicQuery + " ) ";
93
    }
94
    if (refineParams != null && refineParams != '') {
95
      url += refineParams;
96
    }
97
    if (sortBy) {
98
      let sortOptions = sortBy.split(",");
99
      url += "sortBy " + sortOptions[0] + "/sort." + sortOptions[1] + " ";
100
    }
101
    if (refineQuery) {
102
      url += "&" + refineQuery;
103
    }
104
    
105
    url += "&page=" + (page - 1) + "&size=" + size;
106
    url += "&format=json";
107
    
108
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
109
      .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
110
  }
111
  
112
  advancedSearchResults(resultType: string, params: string, page: number, size: number, sortBy: string, properties: EnvProperties, refineParams: string = null, refineFields: string[] = null, refineQuery: string = null): any {
113
    let url = properties.searchAPIURLLAst + "resources2/?format=json";
114
    if (params != null && params != '') {
115
      url += "&query=(" + params + ")";
116
    }
117
    if (sortBy) {
118
      let sortOptions = sortBy.split(",");
119
      url += (params ? " " : "&query=(*) ") + "sortBy " + sortOptions[0] + "/sort." + sortOptions[1] + (params ? " " : " ");
120
    }
121
    if (refineParams != null && refineParams != '') {
122
      url += refineParams;
123
    }
124
    if (refineQuery) {
125
      url += "&" + refineQuery;
126
    }
127
    
128
    url += "&page=" + (page - 1) + "&size=" + size;
129
    // url += "&format=json";
130
    
131
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
132
      .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")]));
133
  }
134
  
135
  searchResultForEntity(resultType: string, params: string, page: number, size: number, properties: EnvProperties): any {
136
    let link = properties.searchAPIURLLAst;
137
    //let url = link+params+"/"+this.getEntityName(resultType,true)+ "?format=json";
138
    //url += "&page="+(page-1)+"&size="+size;
139
    //url += "&sortBy=resultdateofacceptance,descending";
140
    
141
    //let url = link+"/resources2?format=json&query="+params+" sortBy resultdateofacceptance/sort.descending&type="+this.getEntityName(resultType,true);
142
    
143
    let url = link + "/" + this.getEntityName(resultType, true);
144
    url += "?format=json";
145
    url += "&fq=" + params;
146
    url += "&sortBy=resultdateofacceptance,descending";
147
    url += "&page=" + (page - 1) + "&size=" + size;
148
    
149
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
150
      .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
151
  }
152

    
153
//???? why different from above?
154
  searchForDataproviders(resultType: string, params: string, page: number, size: number, properties: EnvProperties): any {
155
    let link = properties.searchAPIURLLAst;
156
    let url = link + params;
157
    url += "&sortBy=resultdateofacceptance,descending";
158
    url += "&page=" + (page - 1) + "&size=" + size + "&format=json";
159
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
160
      .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
161
  }
162
  
163
  searchForMyOrcidLinks(resultType: string, orcidQuery: string, typeQuery: string, page: number, size: number): any {
164
    let url = properties.searchAPIURLLAst + "resources2/?format=json";
165
    if (orcidQuery != null && orcidQuery != '') {
166
      url += "&query=(" + orcidQuery + ")";
167
    }
168
    url += typeQuery;
169
    url += "&page=" + (page - 1) + "&size=" + size;
170
    
171
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
172
      .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties)]));
173
  }
174
  
175
  parseResults(resultType: string, data: any, properties: EnvProperties): SearchResult[] {
176
    let results: SearchResult[] = [];
177
    
178
    let length = Array.isArray(data) ? data.length : 1;
179
    
180
    for (let i = 0; i < length; i++) {
181
      let resData = Array.isArray(data) ? data[i]['result']['metadata']['oaf:entity']['oaf:result'] : data['result']['metadata']['oaf:entity']['oaf:result'];
182
      
183
      var result: SearchResult = new SearchResult();
184
      if (resData['resulttype']) {
185
        result.entityType = resData['resulttype']['classname'];
186
      } else {
187
        result.entityType = resultType;
188
      }
189
      result.types = new Array<string>();
190
      let types = new Set<string>();
191
      
192
      let instance;
193
      let length = Array.isArray(resData['children']['instance']) ? resData['children']['instance'].length : 1;
194
      
195
      for (let i = 0; i < length; i++) {
196
        instance = Array.isArray(resData['children']['instance']) ? resData['children']['instance'][i] : resData['children']['instance'];
197
        this.parsingFunctions.parseTypes(result.types, types, instance);
198
      }
199
      /////////////////////////// Athena Code ///////////////////////////
200
      if (resData['pid']) {
201
        if (!Array.isArray(resData['pid'])) {
202
          if (resData['pid'].classid && resData['pid'].classid == 'doi') {
203
            if (resData['pid'].content != '' && resData['pid'].content != null) {
204
              result.DOIs.push(resData['pid'].content.replace("https://doi.org/", ""));
205
            }
206
          }
207
        } else {
208
          for (let i = 0; i < resData['pid'].length; i++) {
209
            if (resData['pid'][i].classid == 'doi') {
210
              if (resData['pid'][i].content != '' && resData['pid'][i].content != null) {
211
                result.DOIs.push(resData['pid'][i].content.replace("https://doi.org/", ""));
212
              }
213
            }
214
          }
215
        }
216
        result.identifiers = this.parsingFunctions.parseIdentifiers(resData['pid']);
217
      }
218
      /////////////////////////// Athena Code ///////////////////////////
219
      if (resData['programmingLanguage'] && resData['programmingLanguage'] != null) {
220
        result.programmingLanguages = new Array<string>();
221
        
222
        if (!Array.isArray(resData['programmingLanguage'])) {
223
          if (resData['programmingLanguage'].classname != "Undetermined" && resData['programmingLanguage'].classname) {
224
            result.programmingLanguages.push(resData['programmingLanguage'].classname);
225
          }
226
        } else {
227
          for (let i = 0; i < resData['programmingLanguage'].length; i++) {
228
            if (resData['programmingLanguage'][i].classname != "Undetermined" && resData['programmingLanguage'][i].classname) {
229
              result.programmingLanguages.push(resData['programmingLanguage'][i].classname);
230
            }
231
          }
232
        }
233
      }
234
      
235
      if (resData['language'] && resData['language'] != null) {
236
        result.languages = new Array<string>();
237
        
238
        if (!Array.isArray(resData['language'])) {
239
          if (resData['language'].classname != "Undetermined" && resData['language'].classname) {
240
            result.languages.push(resData['language'].classname);
241
          }
242
        } else {
243
          for (let i = 0; i < resData['language'].length; i++) {
244
            if (resData['language'][i].classname != "Undetermined" && resData['language'][i].classname) {
245
              result.languages.push(resData['language'][i].classname);
246
            }
247
          }
248
        }
249
      }
250
      
251
      if (resData['country'] && resData['country'] != null) {
252
        result.countriesForResults = new Array<string>();
253
        
254
        if (!Array.isArray(resData['country'])) {
255
          if (resData['country'].classname != "Undetermined" && resData['country'].classname) {
256
            result.countriesForResults.push(resData['country'].classname);
257
          }
258
        } else {
259
          for (let i = 0; i < resData['country'].length; i++) {
260
            if (resData['country'][i].classname != "Undetermined" && resData['country'][i].classname) {
261
              result.countriesForResults.push(resData['country'][i].classname);
262
            }
263
          }
264
        }
265
      }
266
      
267
      result['title'] = {"name": '', "accessMode": '', "sc39": ''};
268
      
269
      if (Array.isArray(resData['title'])) {
270
        for (let i = 0; i < resData['title'].length; i++) {
271
          if (resData['title'][i] && resData['title'][i].content) {
272
            if (!result.title.name || resData['title'][i].classid == "main title") {
273
              result['title'].name = String(resData['title'][i].content);
274
            }
275
            if (resData['title'][i].classid == "main title") {
276
              break;
277
            }
278
          }
279
        }
280
        if (!result.title.name) {
281
          result['title'].name = "";
282
        }
283
        // result['title'].name = (resData['title'][0] && resData['title'][0].content) ? String(resData['title'][0].content) : "";
284
      } else {
285
        result['title'].name = (resData['title'] && resData['title'].content) ? String(resData['title'].content) : "";
286
      }
287
      
288
      result['id'] = Array.isArray(data) ? data[i]['result']['header']['dri:objIdentifier'] : data['result']['header']['dri:objIdentifier'];
289
      let canId = ParsingFunctions.parseRelCanonicalId(Array.isArray(data) ? data[i] : data, "result");
290
      if (canId) {
291
        result['id'] = canId;
292
      }
293
      result['relcanId'] = result['id'];
294
      
295
      if (resData['bestaccessright'] && resData['bestaccessright'].hasOwnProperty("classname")) {
296
        result['title'].accessMode = resData['bestaccessright'].classname;
297
      }
298
      if (resData['rels'].hasOwnProperty("rel")) {
299
        let relLength = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'].length : 1;
300
        
301
        for (let j = 0; j < relLength; j++) {
302
          let relation = Array.isArray(resData['rels']['rel']) ? resData['rels']['rel'][j] : resData['rels']['rel'];
303
          
304
          if (relation.hasOwnProperty("to")) {
305
            if (relation['to'].class == "isProducedBy") {
306
              result['projects'] = this.parseProjects(result['projects'], relation);
307
            }
308
          }
309
        }
310
      }
311
      
312
      if (resData.hasOwnProperty("creator") && resData['creator'] != null) {
313
        if (result['authors'] == undefined) {
314
          result['authors'] = new Array<{ "fullName": string, "orcid": string, "orcid_pending": string }>();
315
        }
316
        
317
        let authors = resData['creator'];
318
        let length = Array.isArray(authors) ? authors.length : 1;
319
        
320
        for (let i = 0; i < length; i++) {
321
          let author = Array.isArray(authors) ? authors[i] : authors;
322
          if (author) {
323
            if(author.orcid) {
324
              author.orcid = author.orcid.toUpperCase();
325
            }
326
            if(author.orcid_pending) {
327
              author.orcid_pending = author.orcid_pending.toUpperCase();
328
            }
329
            result['authors'][author.rank] = {
330
              "fullName": author.content,
331
              "orcid": author.orcid,
332
              "orcid_pending": author.orcid_pending
333
            };
334
          }
335
        }
336
        result.authors = result.authors.filter(function (item) {
337
          return (item != undefined && item.fullName != undefined);
338
        });
339
      }
340
      
341
      var date: string = (resData.dateofacceptance) + ""; // transform to string in case it is an integer
342
      result.year = (date && (date).indexOf('-') !== -1) ? date.split('-')[0] : date;
343
      
344
      if (!Array.isArray(resData.description)) {
345
        result.description = (resData.description) ? String(resData.description) : "";
346
      } else {
347
        result.description = (resData.description[0]) ? String(resData.description[0]) : "";
348
      }
349
      
350
      if (result.description && result.description.length > this.sizeOfDescription) {
351
        result.description = result.description.substring(0, this.sizeOfDescription) + "...";
352
      }
353
      
354
      if (resData.embargoenddate && resData.embargoenddate != '') {
355
        result.embargoEndDate = Dates.getDate(resData.embargoenddate);
356
      }
357
      
358
      if (!Array.isArray(resData.publisher)) {
359
        result.publisher = resData.publisher;
360
      } else {
361
        for (let i = 0; i < resData.publisher.length; i++) {
362
          if (result.publisher != undefined) {
363
            result.publisher += ', ' + resData['publisher'][i];
364
          } else {
365
            result.publisher = resData['publisher'][i];
366
          }
367
        }
368
      }
369
      if(resData['context'] != null) {
370
        result.enermapsId = ParsingFunctions.getEnermapsConceptId(this.parsingFunctions.parseContexts(resData['context']));
371
      }
372
      results.push(result);
373
    }
374
    
375
    return results;
376
  }
377
  
378
  parseProjects(projects: {
379
    "id": string, "acronym": string, "title": string,
380
    "funderShortname": string, "funderName": string,
381
    "code": string
382
  }[], relation: any): {
383
    "id": string, "acronym": string, "title": string,
384
    "funderShortname": string, "funderName": string,
385
    "code": string
386
  }[] {
387
    if (projects == undefined) {
388
      projects = new Array<{
389
        "id": string, "acronym": string, "title": string,
390
        "funderShortname": string, "funderName": string,
391
        "code": string
392
      }>();
393
    }
394
    
395
    let countProjects = projects.length;
396
    
397
    projects[countProjects] = {
398
      "id": "", "acronym": "", "title": "",
399
      "funderShortname": "", "funderName": "",
400
      "code": ""
401
    };
402
    
403
    if (relation.title != 'unidentified') {
404
      projects[countProjects]['id'] = relation['to'].content;
405
      projects[countProjects]['acronym'] = relation.acronym;
406
      projects[countProjects]['title'] = relation.title;
407
      projects[countProjects]['code'] = relation.code;
408
    } else {
409
      projects[countProjects]['id'] = "";
410
      projects[countProjects]['acronym'] = "";
411
      projects[countProjects]['title'] = "";
412
      projects[countProjects]['code'] = "";
413
    }
414
    
415
    if (relation.hasOwnProperty("funding")) {
416
      let fundingLength = Array.isArray(relation['funding']) ? relation['funding'].length : 1;
417
      
418
      for (let z = 0; z < fundingLength; z++) {
419
        let fundingData = Array.isArray(relation['funding']) ? relation['funding'][z] : relation['funding'];
420
        
421
        if (fundingData.hasOwnProperty("funder")) {
422
          projects[countProjects]['funderShortname'] = fundingData['funder'].shortname;
423
          projects[countProjects]['funderName'] = fundingData['funder'].name;
424
        }
425
      }
426
    }
427
    
428
    return projects;
429
  }
430
  
431
  parseRefineResults(id: string, data: any): any {
432
    var results: any = [];
433
    if (data.hasOwnProperty("resulthostingdatasource")) {
434
      let length = Array.isArray(data['resulthostingdatasource']) ? data['resulthostingdatasource'].length : 1;
435
      
436
      for (let i = 0; i < length; i++) {
437
        let datasource = Array.isArray(data['resulthostingdatasource']) ? data['resulthostingdatasource'][i] : data['resulthostingdatasource'];
438
        
439
        let result: { "name": string, "id": string, "count": number } = {"name": "", "id": "", "count": 0};
440
        result['name'] = datasource.name;
441
        result['id'] = datasource.id.split("||")[0];
442
        result['count'] = datasource.count;
443
        
444
        if (result['id'] != id && result['name'] != "Unknown Repository") {
445
          results.push(result);
446
        }
447
      }
448
    }
449
    return results;
450
  }
451
  
452
  private numOfResults(url: string, properties: EnvProperties): any {
453
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
454
      .pipe(map(res => res['total']));
455
  }
456
  
457
  numOfEntityResults(resultType: string, id: string, entity: string, properties: EnvProperties): any {
458
    var parameters: string = "";
459
    parameters = this.getEntityName(entity, true) + "/" + id + "/" + this.getEntityName(resultType, true) + "/count";
460
    let url = properties.searchAPIURLLAst + parameters + "?format=json";
461
    return this.numOfResults(url, properties);
462
  }
463
  
464
  numOfResearchOutcomes(params: string, properties: EnvProperties, refineParams: string = null): any {
465
    let url = properties.searchAPIURLLAst + "resources2/?format=json&size=0&type=results";
466
    if (params.length > 0) {
467
      // var DOIs:string[] = DOI.getDOIsFromString(params);
468
      // var doisParams = "";
469
      //
470
      // for(var i =0 ;i < DOIs.length; i++){
471
      //   doisParams+=(doisParams.length > 0?"&":"")+'doi="'+ DOIs[i]+'"';
472
      // }
473
      // if(doisParams.length > 0){
474
      //   url += "&"+doisParams;
475
      // }else{
476
      //   url += "&query=" + StringUtils.URIEncode(params);
477
      // }
478
      url += "&query=" + params;
479
    }
480
    
481
    if (refineParams != null && refineParams != '') {
482
      url += refineParams;
483
    }
484
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
485
      .pipe(map(res => res['meta']['total']));
486
  }
487
  
488
  numOfSearchResults(resultType: string, params: string, properties: EnvProperties, refineParams: string = null): any {
489
    let url = properties.searchAPIURLLAst + this.getEntityName(resultType, true) + "/count?format=json";
490
    if (params.length > 0) {
491
      var DOIs: string[] = DOI.getDOIsFromString(params);
492
      var doisParams = "";
493
      
494
      for (var i = 0; i < DOIs.length; i++) {
495
        doisParams += (doisParams.length > 0 ? "&" : "") + 'doi="' + DOIs[i] + '"';
496
      }
497
      if (doisParams.length > 0) {
498
        url += "&" + doisParams;
499
      } else {
500
        url += "&q=" + StringUtils.URIEncode(params);
501
      }
502
    }
503
    
504
    if (refineParams != null && refineParams != '') {
505
      url += refineParams;
506
    }
507
    return this.numOfResults(url, properties);
508
  }
509
  
510
  numOfSearchResultsLinkedToPub(resultType: string, properties: EnvProperties): any {
511
    let url = properties.searchAPIURLLAst + "resources?query=" + encodeURIComponent("( (oaftype exact result) and (resulttypeid exact " + resultType + ") and (relresulttype=publication)  )") + "&page=0&size=0&format=json";
512
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
513
      .pipe(map(res => res['meta']['total']));
514
  }
515
  
516
  countTotalResults(resultType: string, properties: EnvProperties, refineParams: string = null): any {
517
    let url = properties.searchAPIURLLAst + this.getEntityName(resultType, true) + "/count?format=json" + refineParams;
518
    return this.numOfResults(url, properties);
519
  }
520
  
521
  /*
522
      private quote(word: any): string {
523
          return '"'+word+'"';
524
      }
525
  */
526
  
527
  private getEntityName(entityType: string, plural: boolean) {
528
    if (entityType == "publication" || entityType == "dataset" || entityType == "organization" || entityType == "datasource" || entityType == "project") {
529
      if (plural) {
530
        return entityType + "s";
531
      } else {
532
        return entityType;
533
      }
534
    } else {
535
      return entityType;
536
    }
537
  }
538
}
(19-19/23)