Project

General

Profile

1
import {Injectable} from '@angular/core';
2
import {HttpClient, HttpErrorResponse} from "@angular/common/http";
3
import {throwError} from 'rxjs';
4
import {ResultLandingInfo} from '../../utils/entities/resultLandingInfo';
5
import {EnvProperties} from '../../utils/properties/env-properties';
6
import {ParsingFunctions} from '../landing-utils/parsingFunctions.class';
7
import {map} from "rxjs/operators";
8

    
9
@Injectable()
10
export class ResultLandingService {
11

    
12
  constructor(private http: HttpClient ) {
13
    this.parsingFunctions = new ParsingFunctions();
14
  }
15

    
16
  public parsingFunctions: ParsingFunctions;
17
  resultLandingInfo: ResultLandingInfo;
18

    
19
  getResultLandingInfo (id: string, type: string, properties: EnvProperties): any {
20
    let url = properties.searchAPIURLLAst;
21
    if (type === 'publication') {
22
      url += 'publications/';
23
    } else if (type === 'dataset') {
24
      url += 'datasets/';
25
    } else if (type === 'software') {
26
      url += 'software/';
27
    } else if (type === 'orp') {
28
      url += 'other/';
29
    }
30
    url += id + '?format=json';
31

    
32
    return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url)
33
      .pipe(map(res => [res['result']['header']['dri:status'], res['result']['metadata']['oaf:entity'], res]))
34
      .pipe(map(res => [
35
        res[1]['oaf:result'],                 // 0
36
        res[1]['oaf:result']['title'],        // 1
37
        res[1]['oaf:result']['rels']['rel'],  // 2
38
        res[1]['oaf:result']['children'],     // 3
39
        res[1]['oaf:result']['pid'],          // 4
40
        res[1]['oaf:result']['journal'],      // 5
41
        res[1]['oaf:result']['language'],     // 6
42
        res[1]['oaf:result']['subject'],      // 7
43
        res[1]['oaf:result']['context'],      // 8
44
        res[1]['oaf:result']['creator'],      // 9
45
        res[1]['oaf:result']['country'] ,     // 10
46
        res[1]['oaf:result']['programmingLanguage'],              // 11 - software
47
        //res[1]['oaf:result']['resulttype'],
48
        (res[1]['extraInfo'] !== undefined && res[1]['extraInfo']['citations'] !== undefined)
49
          ? res[1]['extraInfo']['citations']['citation'] : null,  // 12
50
        res[0],                               // 13
51
        res[2]                                // 14
52
      ]))
53
      .pipe(map(res => this.parseResultLandingInfo(res, properties)));
54
  }
55

    
56
  private handleError (error: HttpErrorResponse) {
57
    // in a real world app, we may send the error to some remote logging infrastructure
58
    // instead of just logging it to the console
59
    console.log(error);
60
    return throwError(error  || 'Server error');
61
  }
62

    
63
  parseResultLandingInfo (data: any, properties: EnvProperties): any {
64
    this.resultLandingInfo = new ResultLandingInfo();
65

    
66
    // res
67
    this.resultLandingInfo.record = data[14];
68

    
69
    // res['result']['metadata']['oaf:entity']['oaf:result']
70
    if (data[0] != null) {
71
      let date: string = (data[0].dateofacceptance) + ''; // transform to string in case it is an integer
72
      this.resultLandingInfo.date  = (date && (date).indexOf('-') !== -1) ? date.split('-')[0] : date;
73
      this.resultLandingInfo.dateofacceptance = data[0].dateofacceptance;
74
      this.resultLandingInfo.publisher = data[0].publisher;
75
      if(!Array.isArray(data[0].description)) {
76
        this.resultLandingInfo.description = String(data[0].description);
77
      } else {
78
        this.resultLandingInfo.description = String(data[0].description[0]);
79
      }
80
      this.resultLandingInfo.embargoEndDate = data[0].embargoenddate;
81
    }
82

    
83
    if(data[0]['bestaccessright'] && data[0]['bestaccessright'].hasOwnProperty("classid")) {
84
      this.resultLandingInfo.accessMode = data[0]['bestaccessright'].classid;
85
    }
86

    
87
    // res['result']['metadata']['oaf:entity']['oaf:result']['title']
88
    if(data[1] != null) {
89
      if(Array.isArray(data[1])) {
90
        this.resultLandingInfo.title = String(data[1][0].content);
91
        if(data[1][1].classid === 'subtitle') {
92
          this.resultLandingInfo.subtitle = String(data[1][1].content);
93
        }
94
      } else {
95
        this.resultLandingInfo.title = String(data[1].content);
96
      }
97
    }
98

    
99
    // res['result']['metadata']['oaf:entity']['oaf:result']['rels']['rel']
100
    if(data[2] != null) {
101
      let relation;
102
      let length = Array.isArray(data[2]) ? data[2].length : 1;
103

    
104
      for(let i=0; i<length; i++) {
105
        relation = Array.isArray(data[2]) ? data[2][i] : data[2];
106
        if(relation.hasOwnProperty("to")) {
107
          if(relation['to'].class == "isProducedBy") {
108
            this.resultLandingInfo.fundedByProjects = this.parsingFunctions.parseFundingByProjects(this.resultLandingInfo.fundedByProjects, relation, this.resultLandingInfo.projectsProvenanceVocabulary);
109
          } else if(relation['to'].class == "isRelatedTo") {
110
            let provenanceAction: string;
111
            if(relation.provenanceaction in this.resultLandingInfo.researchResultsProvenanceVocabulary) {
112
              provenanceAction = this.resultLandingInfo.researchResultsProvenanceVocabulary[relation.provenanceaction];
113
            } else {
114
              provenanceAction = "Other";
115
            }
116

    
117
            this.resultLandingInfo.relatedResearchResults = this.parsingFunctions.parseRelatedResearchResults(this.resultLandingInfo.relatedResearchResults, relation, provenanceAction);
118
          } else if(relation['to'].class == "hasAmongTopNSimilarDocuments") {
119
            this.resultLandingInfo.similarResearchResults = this.parsingFunctions.parseSimilarResearchResults(this.resultLandingInfo.similarResearchResults, relation);
120
          } else if(relation['to'].class == "hasAuthorInstitution") {
121
            this.resultLandingInfo.organizations = this.parseRelatedOrganizations(this.resultLandingInfo.organizations, relation);
122
          }
123
        }
124
      }
125
    }
126

    
127
    // res['result']['metadata']['oaf:entity']['oaf:result']['children']
128
    if(data[3] != null) {
129
      if(data[3].hasOwnProperty("result")) {
130
        this.resultLandingInfo.deletedByInferenceIds = [];
131
        let length = Array.isArray(data[3]['result']) ? data[3]['result'].length : 1;
132

    
133
        for(let i=0; i<length; i++) {
134
          let result = Array.isArray(data[3]['result']) ? data[3]['result'][i] : data[3]['result'];
135
          this.resultLandingInfo.deletedByInferenceIds.push(result.objidentifier);
136
        }
137

    
138
      }
139

    
140
      if(data[3].hasOwnProperty("instance")) {
141
        this.resultLandingInfo.hostedBy_collectedFrom = new Array<{"downloadName": string, "downloadUrl": string[], "collectedName": string, "collectedId": string, "accessMode": string[], "bestAccessMode": string, "type": string, "year":string}>();
142

    
143

    
144
        this.resultLandingInfo.types = new Array<string>();
145
        let types = new Set<string>();
146

    
147
        let counter = 0;
148
        let instance;
149

    
150
        let length = Array.isArray(data[3]['instance']) ? data[3]['instance'].length : 1;
151

    
152
        for(let i=0; i<length; i++) {
153
          instance = Array.isArray(data[3]['instance']) ? data[3]['instance'][i] : data[3]['instance'];
154

    
155
          this.parsingFunctions.parseTypes(this.resultLandingInfo.types, types, instance);
156

    
157
          if(instance.hasOwnProperty("webresource")) {
158
            let url;
159
            if(!Array.isArray(instance['webresource'])) {
160
              url = instance['webresource'].url;
161
            } else{
162
              url = instance['webresource'][0].url;
163
            }
164

    
165
            /**********************************************************/
166
            if(instance.hasOwnProperty("hostedby")) {
167
              counter = this.parsingFunctions.parseHostedBy_collectedFrom(this.resultLandingInfo.hostedBy_collectedFrom, instance, data[0], url, counter/*, this.resultLandingInfo.title*/, this.resultLandingInfo.accessMode);
168
            }
169
            /**********************************************************/
170
          }
171
        }
172
      }
173

    
174
      if(data[3].hasOwnProperty("externalreference")) {
175
        let externalResults: [Map<string, Map<string, string>>, { "name": string, "url": string}[]] = this.parseBioentitiesAndSoftware(data[3]);
176
        this.resultLandingInfo.bioentities = externalResults[0];
177
        this.resultLandingInfo.software = externalResults[1];
178
      }
179
    }
180

    
181
    // res['result']['metadata']['oaf:entity']['oaf:result']['pid']
182
    if(data[4] != null) {
183
      this.resultLandingInfo.identifiers = this.parsingFunctions.parseIdentifiers(data[4]);
184
    }
185

    
186
    // res['result']['metadata']['oaf:entity']['oaf:result']['journal']
187
    if(data[5] != null) {
188
      this.resultLandingInfo.journal = {"journal": "", "issn": "", "lissn": "", "eissn": "", "issue": "", "volume": "", "start_page": "", "end_page": ""}
189

    
190
      this.resultLandingInfo.journal['journal'] = data[5].content;
191
      this.resultLandingInfo.journal['issn'] = data[5].issn;
192
      this.resultLandingInfo.journal['lissn'] = data[5].lissn;
193
      this.resultLandingInfo.journal['eissn'] = data[5].eissn;
194
      this.resultLandingInfo.journal['issue'] = data[5].iss;
195
      this.resultLandingInfo.journal['volume'] = data[5].vol;
196
      this.resultLandingInfo.journal['start_page'] = data[5].sp;
197
      this.resultLandingInfo.journal['end_page'] = data[5].ep;
198
    }
199

    
200
    // res['result']['metadata']['oaf:entity']['oaf:result']['language']
201
    if(data[6] != null) {
202
      this.resultLandingInfo.languages = this.parsingFunctions.parseLanguages(data[6]);
203
    }
204

    
205
    // res['result']['metadata']['oaf:entity']['oaf:result']['country']
206
    if(data[10] != null) {
207
      this.resultLandingInfo.countries = this.parsingFunctions.parseCountries(data[10]);
208
    }
209

    
210
    // res['result']['metadata']['oaf:entity']['oaf:result']['subject']
211
    if(data[7] != null) {
212
      let subjectResults: [string[], Map<string, string[]>, Map<string, string[]>] = this.parsingFunctions.parseAllSubjects(data[7]);
213
      this.resultLandingInfo.subjects = subjectResults[0];
214
      this.resultLandingInfo.otherSubjects = subjectResults[1];
215
      this.resultLandingInfo.classifiedSubjects = subjectResults[2];
216
    }
217

    
218
    this.resultLandingInfo.hostedBy_collectedFrom = this.parsingFunctions.addPublisherToHostedBy_collectedFrom(
219
      this.resultLandingInfo.hostedBy_collectedFrom, this.resultLandingInfo.publisher,
220
      this.resultLandingInfo.journal, this.resultLandingInfo.identifiers);
221

    
222
    // res['result']['metadata']['oaf:entity']['oaf:result']['programmingLanguage']
223
    if(data[11] != null) {
224
      this.resultLandingInfo.programmingLanguages = this.parsingFunctions.parseProgrammingLanguages(data[11]);
225
    }
226

    
227
    // res['result']['metadata']['oaf:entity']['extraInfo']['citations']['citation']
228
    if(data[12] != null) {
229
      this.resultLandingInfo.references = this.parsingFunctions.parseReferences(data[12]);
230
    }
231

    
232
    // res['result']['metadata']['oaf:entity']['oaf:result']['context']
233
    if(data[8] != null) {
234
      this.resultLandingInfo.contexts = this.parsingFunctions.parseContexts(data[8]);
235
    }
236

    
237
    // res['result']['header']['dri:status']
238
    if(data[13] != null && data[13] == "under curation") {
239
      this.resultLandingInfo.underCurationMessage = true;
240
    } else {
241
      this.resultLandingInfo.underCurationMessage = false;
242
    }
243

    
244
    // res['result']['metadata']['oaf:entity']['oaf:result']['creator']
245
    if(data[9] != null) {
246
      if(this.resultLandingInfo.authors == undefined) {
247
        this.resultLandingInfo.authors = new Array<{"fullName": string, "orcid": string}>();
248
      }
249

    
250
      let authors = data[9];
251
      let length = Array.isArray(authors) ? authors.length : 1;
252

    
253
      for(let i=0; i<length; i++) {
254
        let author = Array.isArray(authors) ? authors[i] : authors;
255
        if(author) {
256
          this.resultLandingInfo['authors'][author.rank] = {"fullName": author.content, "orcid": author.ORCID};
257
        }
258
      }
259
      this.resultLandingInfo.authors = this.resultLandingInfo.authors.filter(function (item) {
260
        return (item != undefined && item.fullName != undefined);
261
      });
262
    }
263

    
264
    if(this.resultLandingInfo.relatedResearchResults) {
265
      let self = this;
266
      this.resultLandingInfo.relatedResearchResults.forEach(function (value, key, map) {
267
        self.resultLandingInfo.relatedResearchResults.set(key, self.parsingFunctions.sortByPercentage(value));
268
      });
269
    }
270
    this.resultLandingInfo.similarResearchResults = this.parsingFunctions.sortByPercentage(this.resultLandingInfo.similarResearchResults);
271

    
272
    return this.resultLandingInfo;
273
  }
274

    
275
  parseRelatedOrganizations(organizations: {"name": string, "shortname":string, "id": string, "websiteUrl": string, "country": string, "trust": number}[], relation: any):
276
    {"name": string, "shortname":string, "id": string, "websiteUrl": string, "country": string, "trust": number}[] {
277
    if(organizations == undefined) {
278
      organizations = new Array<{
279
        "name": string, "shortname": string,
280
        "id": string, "websiteUrl": string,
281
        "country": string, "trust": number}>();
282
    }
283

    
284
    let organization: { "name": string, "shortname": string,
285
      "id": string, "websiteUrl": string,
286
      "country": string, "trust": number
287
    } = {
288
      "name": "", "shortname": "",
289
      "id": "", "websiteUrl": "",
290
      "country": "", "trust": null
291
    };
292

    
293
    organization.id = relation['to'].content;
294
    organization.name = relation.legalname;
295
    organization.shortname = relation.legalshortname;
296
    organization.websiteUrl = relation.websiteurl;
297
    if(relation.country) {
298
      organization.country = relation.country.classname;
299
    }
300
    if(relation.trust) {
301
      organization.trust = Math.round(relation.trust*100);
302
    }
303

    
304
    organizations.push(organization);
305
    return organizations;
306
  }
307

    
308
  parseBioentitiesAndSoftware(children: any) : [Map<string, Map<string, string>>, { "name": string, "url": string}[]] {
309
    let bioentities: Map<string, Map<string, string>>;
310
    let software: {"name": string, "url": string}[];
311

    
312
    let length = Array.isArray(children['externalreference']) ? children['externalreference'].length : 1;
313

    
314
    let externalreference;
315
    for(let i=0; i<length; i++) {
316
      externalreference = Array.isArray(children['externalreference']) ? children['externalreference'][i] : children['externalreference'];
317

    
318
      if(externalreference.hasOwnProperty("qualifier")) {
319
        if(externalreference['qualifier'].classid == "accessionNumber") {
320

    
321
          if(bioentities == undefined) {
322
            bioentities = new Map<string, Map<string, string>>();
323
          }
324

    
325
          if(!bioentities.has(externalreference.sitename)) {
326
            bioentities.set(externalreference.sitename, new Map<string, string>());
327
          }
328
          bioentities.get(externalreference.sitename).set(externalreference.refidentifier, externalreference.url);
329

    
330
        } else if(externalreference['qualifier'].classid == "software") {
331

    
332
          if(software == undefined) {
333
            software = new Array<{"name": string, "url": string}>();
334
          }
335

    
336
          software.push({"name": externalreference.sitename, "url": externalreference.url});
337
        }
338
      }
339
    }
340

    
341
    return [bioentities, software];
342
  }
343

    
344
  getOpenCitations(id: string, properties:EnvProperties) {
345
    //https://services.openaire.eu/opencitations/getCitations?id=doajarticles::2634200c24772ee8f10232d3e184ec65
346
    let url = properties.openCitationsAPIURL+id;// "https://services.openaire.eu/opencitations/getCitations?id=" + id;
347
    let key = url;
348

    
349
    //return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url)
350
    return this.http.get(url)
351
      .pipe(map(res => [res['total'], this.parseOpenCitations(res['results'])]));
352
  }
353

    
354
  parseOpenCitations(openCitations: any): {"url": string, "title": string, "year": string, "doi": string, "authors": string[]}[] {
355
    //title, doi, authors
356
    let citations = new Array<{"url": string, "title": string, "year": string, "doi": string, "authors": string[]}>();
357

    
358
    let openCitation;
359

    
360
    let length = Array.isArray(openCitations) ? openCitations.length : 1;
361
    for(let i=0; i<length; i++) {
362
      openCitation = Array.isArray(openCitations) ? openCitations[i] : openCitations;
363

    
364
      let citation: {"url": string, "title": string,  "year": string, "doi": string, "authors": string[]} = {"url": "", "title": "", "year": "", "doi": "", "authors": []};
365

    
366
      if(openCitation && openCitation.id) {
367
        citation.url = openCitation.id;
368
        citation.title = openCitation.title;
369
        //citation.type = openCitation.type;
370
        citation.year = (openCitation.pubDate && (openCitation.pubDate).indexOf('-') !== -1)?openCitation.pubDate.split('-')[0]:openCitation.pubDate;
371
        citation.doi = openCitation.doi;
372

    
373
        let authorsLength = Array.isArray(openCitation.authors) ? openCitation.authors.length : 1;
374
        for(let i=0; i<authorsLength; i++) {
375
          let author = Array.isArray(openCitation.authors) ? openCitation.authors[i] : openCitation.authors;
376

    
377
          if(author) {
378
            let lastFirstName: string = "";
379
            if(author.lastName) {
380
              lastFirstName = author.lastName;
381
            }
382
            if(author.lastName && author.firstName) {
383
              lastFirstName += ", ";
384
            }
385
            if(author.firstName) {
386
              lastFirstName += author.firstName;
387
            }
388

    
389
            if(lastFirstName) {
390
              citation.authors.push(lastFirstName);
391
            }
392
          }
393
        }
394
        citations.push(citation);
395
      }
396
    }
397
    return citations;
398
  }
399
}
(4-4/4)