Project

General

Profile

1
import {Component, Input, Output, EventEmitter,ViewChild} from '@angular/core';
2
import {Observable}       from 'rxjs/Observable';
3
import {SearchCrossrefService} from '../../claim-utils/service/searchCrossref.service';
4
import {SearchDataciteService} from '../../claim-utils/service/searchDatacite.service';
5

    
6
import {ModalLoading} from '../../../utils/modal/loading.component';
7
import {Dates, DOI} from '../../../utils/string-utils.class';
8
import {OpenaireProperties} from '../../../utils/properties/openaireProperties';
9
import {ClaimResult} from '../../claim-utils/claimEntities.class';
10

    
11

    
12
@Component({
13
    selector: 'bulk-claim',
14
    template: `
15
    <div class="uk-animation  " style=" ">
16
      <form class=" uk-padding uk-panel  uk-background-muted ">
17

    
18
        <div class="uk-clearfix">
19
            <a  class="uk-float-right" uk-toggle="target: #uploadInfo; animation:  uk-animation-fade"><span class="uk-icon">
20
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" icon="info" ratio="1"><path d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"></path><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"></circle></svg>
21
</span> What is upload mode? </a>
22
        </div>
23
        <div id="uploadInfo" class="uk-card uk-card-default uk-card-body uk-margin-small" hidden>
24
            <a uk-toggle="target: #uploadInfo; animation:  uk-animation-fade" class="uk-float-right"><span class="uk-icon">
25
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" icon="close" ratio="1"><path fill="none" stroke="#000" stroke-width="1.06" d="M16,16 L4,4"></path><path fill="none" stroke="#000" stroke-width="1.06" d="M16,4 L4,16"></path></svg>
26
</span></a>
27
             <div class="uk-text-bold"><span class="uk-icon">
28
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" icon="info" ratio="1"><path d="M12.13,11.59 C11.97,12.84 10.35,14.12 9.1,14.16 C6.17,14.2 9.89,9.46 8.74,8.37 C9.3,8.16 10.62,7.83 10.62,8.81 C10.62,9.63 10.12,10.55 9.88,11.32 C8.66,15.16 12.13,11.15 12.14,11.18 C12.16,11.21 12.16,11.35 12.13,11.59 C12.08,11.95 12.16,11.35 12.13,11.59 L12.13,11.59 Z M11.56,5.67 C11.56,6.67 9.36,7.15 9.36,6.03 C9.36,5 11.56,4.54 11.56,5.67 L11.56,5.67 Z"></path><circle fill="none" stroke="#000" stroke-width="1.1" cx="10" cy="10" r="9"></circle></svg>
29
</span> Upload information:</div>
30
             Upload a csv file containing a list of DOIs. For each DOI found in the file, metadata will be fetched from CrossRef or Datacite.
31
              Available results will be added to your selected resarch results list in order to be linked with the selected Projects and Contexts.
32

    
33
                <div class="uk-article-meta">
34
                 CSV format:
35
                 <ul class="uk-list">
36
                   <li>The format of CSV file should be "DOI","ACCESS_MODE","DATE".</li>
37
                   <li>The value "DOI" is required </li>
38
                    <li>Access mode column should have values: "OPEN","CLOSED" or "EMBARGO".</li>
39
                    <li>Date column valid format is YYYY-MM-DD and is required when access mode has value EMBARGO.</li>
40
                    <li>In case access mode is not available default value is "OPEN".</li>
41
                  </ul>
42
                </div>
43
         </div>
44

    
45

    
46

    
47

    
48
          <div for="exampleInputFile">Upload a DOI csv file:</div>
49
          <label for="exampleInputFile">Select a file</label>
50
          <input id="exampleInputFile" class="uk-width-1-2" type="file"  (change)="fileChangeEvent($event)" placeholder="Upload file..." />
51
          <button class="uk-button uk-button-success" [class.disabled]="!enableUpload" type="button" (click)="upload()">Upload</button>
52

    
53
          <div *ngIf="showReport"  uk-alert  class="uk-alert uk-alert-primary" role="alert" >
54
            <a class="uk-alert-close" uk-close></a>
55
            <div>Uploaded file contains {{allIds.length}} rows. {{foundIds.length}} results were sucefully  fetched from CrossRef and Datacite.</div>
56
            <div *ngIf ="duplicateIds.length > 0"  >{{duplicateIds.length}} duplicate DOIs.</div>
57
            <div *ngIf = "notFoundIds.length > 0"   >Couldn't be found:
58
              <ul class="">
59
                <li *ngFor="let id of notFoundIds">"{{id}}"</li>
60
               </ul>
61
            </div>
62
            <div *ngIf = "noValidIds.length > 0"   >No valid DOIs:
63
              <ul class="">
64
                <li *ngFor="let id of noValidIds">"{{id}}"</li>
65
               </ul>
66
            </div>
67
            <div *ngIf = "allIds.length == 0 || foundIds.length == 0"   > Please make sure you are using the right format for the csv file... </div>
68

    
69
          </div>
70
          <div *ngIf="errorMessage.length > 0 " class="uk-alert uk-alert-danger" role="alert">{{errorMessage}}</div>
71
          <modal-loading [message]= "'Uploading, reading and fetching results from your document. Please give us a moment..'"></modal-loading>
72
       </form>
73

    
74

    
75

    
76
</div>
77
    `
78

    
79
})
80
//[(ngModel)]="date"
81
export class BulkClaimComponent {
82
  filesToUpload: Array<File>;
83
  navigateTo: string = "Search";
84
  source: string = "crossref";
85
  type : string = "publication";
86
  resultsFromSearch:number;
87
  @Input() public select:boolean = true ;
88
  @Input() public results;
89

    
90
  allIds:string[] = [];
91
  foundIds:string[] = [];
92
  duplicateIds:string[] = [];
93
  notFoundIds:string[] = [];
94
  noValidIds:string[] = [];
95
  showReport:boolean = false;
96
  showInfo :boolean = false;
97
  @ViewChild (ModalLoading) loading : ModalLoading ;
98
  errorMessage = "";
99
  infoMEssage = "";
100
  enableUpload:boolean = true;
101
  constructor(private _searchCrossrefService: SearchCrossrefService, private _searchDataciteService: SearchDataciteService) {
102
      this.filesToUpload = [];
103
  }
104
  ngOnInit() {}
105

    
106
  upload() {
107
    this.enableUpload = false;
108
    this.showReport = false;
109
    this.errorMessage = "";
110
    if(this.filesToUpload.length == 0){
111
      this.errorMessage = "There is no selected file to upload.";
112
      return ;
113
    }
114
    this.loading.open();
115

    
116
    this.makeFileRequest(OpenaireProperties.getUploadServiceUrl(), [], this.filesToUpload).then((result) => {
117
          var rows = (result as any).split('\n');  // I have used space, you can use any thing.
118
          var i = 0;
119
          this.duplicateIds = [];
120
          this.allIds = [];
121
          this.foundIds = [];
122
          this.noValidIds = [];
123
          this.results.slice(0,this.results.length);
124
          this.notFoundIds = [];
125

    
126
          for(i=0;i<rows.length;i++){
127
            if(rows[i] && rows[i] != null ){
128
              console.log("Row is:" + rows[i]);
129
              var values = rows[i].split(',');
130

    
131
              var id=this.removeDoubleQuotes(values[0]);
132
              if(DOI.isValidDOI(id)){
133
                var accessMode = (values[1] != undefined) ? this.removeDoubleQuotes(values[1]):"OPEN";
134
                accessMode = (this.validateAccessMode(accessMode)?accessMode:"OPEN");
135
                var embargoDate =(values[2] != undefined) ? this.removeDoubleQuotes(values[2]):Dates.getDateToday();
136
                embargoDate = (Dates.isValidDate(embargoDate)?embargoDate:Dates.getDateToday());
137
                if(this.allIds.indexOf(id)>-1){
138
                  this.duplicateIds.push(id);
139
                }else{
140
                  this.allIds.push(id);
141
                  this.fetchResult(id,accessMode,embargoDate);
142
                }
143
             }else{
144
               this.noValidIds.push(id);
145
             }
146
           }
147

    
148
         }
149

    
150
       }, (error) => {
151
         this.enableUpload = true;
152
          console.log(error);
153
          this.loading.close();
154
          this.errorMessage = "An error occured while uploading...";
155
      });
156
  }
157
  private removeDoubleQuotes(value){
158
     if(value.indexOf('"')== 0){
159
        value = value.substring(1,value.length);
160
      }
161
      var index =+value.indexOf('"');
162
      if(index == (value.length - 1) || index == (value.length - 2) ){
163
        value = value.substring(0,index);
164
      }
165
      return value;
166
  }
167
  private validateAccessMode(value){
168
    var accessModes = ["OPEN", "CLOSED", "EMBARGO"];
169
     if(accessModes.indexOf(value) > -1){
170
        return true;
171
      }
172

    
173
      return false;
174
  }
175

    
176
  fileChangeEvent(fileInput: any){
177
      this.filesToUpload = <Array<File>> fileInput.target.files;
178
  }
179

    
180
  makeFileRequest(url: string, params: Array<string>, files: Array<File>) {
181
      return new Promise((resolve, reject) => {
182
          var formData: any = new FormData();
183
          var xhr = new XMLHttpRequest();
184
          for(var i = 0; i < files.length; i++) {
185
              formData.append("uploads[]", files[i], files[i].name);
186
          }
187
          xhr.onreadystatechange = function () {
188
              if (xhr.readyState == 4) {
189
                  if (xhr.status == 200) {
190
                      resolve(xhr.response);
191
                  } else {
192
                      reject(xhr.response);
193
                  }
194
              }
195
          }
196
          xhr.open("POST", url, true);
197
          xhr.send(formData);
198
      });
199
  }
200

    
201
  fetchResult(id:string,accessMode:string,date:string){
202
        this._searchCrossrefService.searchCrossrefByDOIs([id]).subscribe(
203
          data => {
204

    
205
            var crossrefResult = data.items[0];
206
            if(data.items.length > 0){
207
              this.foundIds.push(id);
208
              var result: ClaimResult = ClaimResult.generateResult(crossrefResult, id,"crossref","publication",  crossrefResult.URL, crossrefResult.title, crossrefResult.created['date-time'], accessMode);
209
              result.embargoEndDate = date;
210
              this.results.push(result);
211
              this.endOfFetching();
212
            }else{
213
              this.searchInDatacite(id,accessMode,date);
214
              // this.notFoundIds.push(id);
215
            }
216
           },
217
          err => {
218
            console.log(err);
219
            this.notFoundIds.push(id);
220
            this.endOfFetching();
221
          }
222
        );
223
  }
224
  searchInDatacite(id:string,accessMode:string,date:string){
225
        this._searchDataciteService.getDataciteResultByDOI(id).subscribe(
226
          item => {
227
            var dataciteResult = item.data;
228

    
229
            if(dataciteResult != null &&  dataciteResult.attributes!= null  ){
230

    
231
              this.foundIds.push(id);
232
              var result: ClaimResult = ClaimResult.generateResult(dataciteResult, id,"datacite","dataset",  'http://dx.doi.org/'+dataciteResult.attributes.doi, dataciteResult.attributes.title, dataciteResult.attributes.published, accessMode);
233
              result.embargoEndDate = date;
234
              this.results.push(result);
235
            }else{
236
              this.notFoundIds.push(id);
237
            }
238
            this.endOfFetching();
239
           },
240
          err => {
241
            console.log(err);
242
            this.notFoundIds.push(id);
243
            this.endOfFetching();
244
          }
245
        );
246
  }
247
  endOfFetching(){
248
    if(this.allIds.length == this.foundIds.length+this.notFoundIds.length+ this.duplicateIds.length ){
249
      this.showReport = true;
250
      this.enableUpload = true;
251
      this.loading.close();
252

    
253
    }
254

    
255
  }
256
}
(1-1/2)