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=null) {
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
    if(data == null) {
178
      return results;
179
    }
180

    
181
    let length = Array.isArray(data) ? data.length : 1;
182

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

    
542
  public countCollectedResultsWithFundingInfo(datasourceId: string) {
543
    let url = properties.searchAPIURLLAst + "resources?query=" + encodeURIComponent("(oaftype=result and collectedfromdatasourceid exact \""+datasourceId+"\" and relprojectid=*)") + "&page=0&size=0&format=json";
544
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
545
      .pipe(map(res => res['meta']['total']));
546
  }
547
}
(19-19/23)