Skip to content
Snippets Groups Projects
Commit 2bbc6d40 authored by Baptiste Toulemonde's avatar Baptiste Toulemonde
Browse files

bug fix wip

parent fddfa648
No related branches found
No related tags found
1 merge request!33Feature/maaping decription to tsv
......@@ -6,7 +6,8 @@ export class Property {
public card: string;
public geodcat: boolean;
public isDuplicated?: boolean = false;
public dcatClass?: string;
constructor(name: string, identifier: string, usageNote: string, isDuplicated: boolean, card: string, geodcat:boolean) {
this.property = name;
this.uri = identifier;
......@@ -17,13 +18,30 @@ export class Property {
}
}
export class OldProperty {
public name: string;
public identifier: string;
public usageNote: string;
public isDuplicated?: boolean = false;
constructor(name: string, identifier: string, usageNote: string, isDuplicated: boolean, card: string, geodcat:boolean) {
this.name = name;
this.identifier = identifier;
this.usageNote = usageNote;
this.isDuplicated = isDuplicated;
}
}
export class DatasetPath {
public dcatProperty: Property | string;
public path: string
public path: string;
public dcatClass: string;
constructor(dcatProperty: Property, path: string) {
constructor(dcatProperty: Property, path: string, dcatClass: string) {
this.dcatProperty = dcatProperty;
this.path = path;
this.dcatClass = dcatClass;
}
}
......@@ -44,6 +62,7 @@ export class ResponseFileTsv {
public predicat_id: string;
public object_id: string;
public match_type: string;
public object_category: string;
}
......@@ -9,23 +9,25 @@
</nb-card-body>
</nb-card>
<form #form="ngForm" *ngIf="ontology">
<div class="row">
<p>Upload Or fill out the form with the path corresponding to the dcat property and save a
new
file for next mappings:</p>
<button class="button-center" nbButton status="primary" (click)="openFileInputDialog()">
<nb-icon icon="upload-outline"></nb-icon>Import file
</button>
<input type="file" id="file" (change)="importJson($event)" accept=".json, .tsv" />
</div>
<div class="card-row">
<div class="card-col">
<nb-card size="giant">
<nb-card-header>Dataset</nb-card-header>
<nb-card-body>
<div class="row">
<p>Upload Or fill out the form with the path corresponding to the dcat property and save a
new
file for next mappings:</p>
<button class="button-center" nbButton status="primary" (click)="openFileInputDialog()">
<nb-icon icon="upload-outline"></nb-icon>Import file
</button>
<input type="file" id="file" (change)="importJson($event)" accept=".json, .tsv" />
</div>
<ng-container *ngFor="let dataset of dcatVocabulary ; let index = index">
<ng-container *ngFor="let dataset of datasets ; let index = index">
<nb-form-field>
<div class="row">
......@@ -36,7 +38,7 @@
value="{{dataset.uri}} " disabled style="color: black;" />
<input *ngIf="isMandatory(dataset.card)" nbInput fullWidth type="text"
value="{{dataset.uri}} *" disabled style="color: black;" />
<button nbSuffix nbTooltip="{{dataset.name}}: {{dataset.usageNote}}"
<button nbSuffix nbTooltip="{{dataset.property}}: {{dataset.usageNote}}"
nbTooltipStatus="info" nbButton status="basic" ghost>
<nb-icon [icon]=" 'question-mark-circle-outline' " pack="eva">
</nb-icon>
......@@ -66,12 +68,12 @@
</nb-autocomplete>
</nb-form-field>
</div>
<div class="col-2" *ngIf="isReplicable(dataset.card)" style="margin-left: 10px;">
<button nbButton ghost (click)="addField(index)" *ngIf="!dataset.isDuplicated">
<div class="col-2" *ngIf="isReplicable(dataset.card) " style="margin-left: 10px;">
<button nbButton ghost (click)="addField(index)" *ngIf="dataset.uri !== datasets[index - 1].uri">
<nb-icon icon="plus-outline" status="primary">
</nb-icon>
</button>
<button nbButton ghost *ngIf="dataset.uri === dcatVocabulary[index - 1].uri"
<button nbButton ghost *ngIf="dataset.uri === datasets[index - 1].uri"
(click)="deleteField(index)">
<nb-icon icon="trash-2-outline" status="danger">
</nb-icon>
......@@ -109,7 +111,7 @@
<input *ngIf="isMandatory(distribution.card)" nbInput fullWidth type="text"
value="{{distribution.uri}} *" disabled style="color: black;" />
<button nbSuffix
nbTooltip="{{distribution.name}}: {{distribution.usageNote}}"
nbTooltip="{{distribution.property}}: {{distribution.usageNote}}"
nbTooltipStatus="info" nbButton status="basic" ghost>
<nb-icon [icon]=" 'question-mark-circle-outline' " pack="eva">
</nb-icon>
......@@ -143,11 +145,11 @@
<div class="col-2" *ngIf="isReplicable(distribution.card)"
style="margin-left: 10px;">
<button nbButton ghost (click)="addField(index)"
*ngIf="!distribution.isDuplicated">
*ngIf="distribution.uri !== distributions[index - 1].uri">
<nb-icon icon="plus-outline" status="primary">
</nb-icon>
</button>
<button nbButton ghost *ngIf="distribution.isDuplicated"
<button nbButton ghost *ngIf="distribution.uri === distributions[index - 1].uri"
(click)="deleteField(index)">
<nb-icon icon="trash-2-outline" status="danger">
</nb-icon>
......@@ -183,7 +185,7 @@
*ngFor="let data of datasetMappedMetadatas[index] | keyvalue; trackBy:trackByIndex; ">
<div class="row">
<div class="col-3"><label
for="{{data.key}}">{{dcatVocabulary[data.key].uri}}</label>
for="{{data.key}}">{{datasets[data.key].uri}}</label>
</div>
<div class="col-7">
<ng-template #normal>
......@@ -191,18 +193,18 @@
(ngModelChange)="datasetMappedMetadatas[index].set(data.key, $event)" />
</ng-template>
<ng-container
*ngIf="isArray(data.value) && !isReplicable(dcatVocabulary[data.key].card); else normal">
*ngIf="isArray(data.value) && !isReplicable(datasets[data.key].card); else normal">
<input nbInput [ngModel]="data.value[0]"
(ngModelChange)="datasetMappedMetadatas[index].set(data.key, $event)" />
</ng-container>
<ng-container
*ngIf="isArray(data.value) && isReplicable(dcatVocabulary[data.key].card)">
*ngIf="isArray(data.value) && isReplicable(datasets[data.key].card)">
<ul *ngFor="let val of data.value" style="margin-left: -100px;">
<li>
<div class="row">
<div class="col-3">
<label
for="{{data.key}}">{{dcatVocabulary[data.key].uri}}</label>
for="{{data.key}}">{{datasets[data.key].uri}}</label>
</div>
<div class="col-7">
<input nbInput [ngModel]="val"
......
......@@ -6,13 +6,14 @@ import { FormArray } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { Router } from '@angular/router';
import { FileSaverService } from 'ngx-filesaver';
import { version } from 'process';
import { Observable, of, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from 'src/environments/environment.prod';
import { DatasetCrudService } from '../datasets/services/dataset-crud.service';
import { Property, DatasetPath, Distribution, ResponseFileTsv } from './class/dataset';
import { Property, DatasetPath, Distribution, ResponseFileTsv, OldProperty } from './class/dataset';
import { FeedbackDialogComponent } from './dialog/feedback-dialog/feedback-dialog.component';
import { MappingService } from './service/mapping.service';
......@@ -28,9 +29,9 @@ export class MappingComponent implements OnInit {
check = false;
distributions: Property[] = [];
ontology: string;
urls: any[] = [];
urls: any[] = [];
itemsdataset: any[] = []
dcatVocabulary: Property[];
datasets: Property[];
vocabularies: Property[];
filteredOptions: Observable<string[]>;
keys: string[] = [];
......@@ -69,15 +70,17 @@ export class MappingComponent implements OnInit {
}
selectOntology(): void {
this.dataSetService.getLocally(`./assets/geodcat.json`).subscribe(
this.dataSetService.getLocally(`./assets/geodcat.json`).subscribe(
datasets => {
this.dcatVocabulary = this.ontology === "dcat" ? datasets.filter(d => !d.geodcat) : datasets;
this.vocabularies = this.ontology === "dcat" ? datasets.filter(d => !d.geodcat) : datasets;;
this.datasets = this.ontology === "dcat" ? datasets.filter(d => !d.geodcat) : datasets;
this.vocabularies = this.ontology === "dcat" ? datasets.filter(d => !d.geodcat) : datasets;
this.vocabularies.forEach(dataset => dataset.dcatClass = 'dcat:dataset');
this.selectedPaths = [];
this.dataSetService.getLocally('./assets/distribution.json').subscribe(
(distributions: Distribution[]) => {
this.distributions = this.ontology === "dcat" ? distributions.filter(d => !d.geodcat) : distributions;
this.vocabularies = this.vocabularies.concat(this.ontology === "dcat" ? distributions.filter(d => !d.geodcat) : distributions);
this.distributions.forEach(distribution => distribution.dcatClass = 'dcat:distribution');
this.vocabularies = this.vocabularies.concat(this.ontology === "dcat" ? this.distributions.filter(d => !d.geodcat) : distributions);
this.distributionSelectedPaths = [];
}
);
......@@ -86,8 +89,8 @@ export class MappingComponent implements OnInit {
console.error(error);
},
);
}
}
mapFromXslt() {
......@@ -115,7 +118,7 @@ export class MappingComponent implements OnInit {
const array: string[] = (classDcat === "dataset") ? this.selectedPaths : this.distributionSelectedPaths
for (let i = 0; i < array.length; i++) {
if (array[i] && array.length > 0) {
let tab = array[i].split(' : ') ;
let tab = array[i].split(' : ');
this.type == "Dataverse" ? mappedMetadata.set(i, this.getValueCustom(tab, item)) : mappedMetadata.set(i, this.getValueCustom(tab, item));
}
}
......@@ -131,9 +134,9 @@ export class MappingComponent implements OnInit {
this.loading = true;
const requestPromises: Promise<any>[] = [];
for (let i = 0; i < this.datasetMappedMetadatas.length; i++) {
properties = this.buildRDF(this.dcatVocabulary, this.datasetMappedMetadatas, i);
properties = this.buildRDF(this.datasets, this.datasetMappedMetadatas, i);
data = this.getDatasetEmpty(properties);
let requestPromise = this.dataSetService.createDataset(data).then((resp: HttpResponse<any>) => {
......@@ -142,7 +145,7 @@ export class MappingComponent implements OnInit {
} else {
notPostedDatasets.push(this.ids[i]);
}
const location = resp.headers.get("location");
const datasetId = location.substring(location.search("dataset/") + 8, location.length);
if (this.distributionMappedMetadatas.length > 0) {
......@@ -167,31 +170,31 @@ export class MappingComponent implements OnInit {
}
buildRDF(vocabularies: Property[], array: Map<number, string>[], i: number): string {
let properties = "";
let version = false;
array[i].forEach((value: string, key: number) => {
let uri = vocabularies[key].uri;
if (uri === 'dct:hasVersion') {
version = true;
}
let properties = "";
let version = false;
array[i].forEach((value: string, key: number) => {
let uri = vocabularies[key].uri;
if (uri === 'dct:hasVersion') {
version = true;
}
if (Array.isArray(value)) {
if (this.isReplicable(this.getCard(uri))) {
value.forEach(v => {
properties += this.writeRdf(uri, v);
})
} else {
properties += this.writeRdf(uri, value[0]);
}
if (Array.isArray(value)) {
if (this.isReplicable(this.getCard(uri))) {
value.forEach(v => {
properties += this.writeRdf(uri, v);
})
} else {
properties += this.writeRdf(uri, value);
properties += this.writeRdf(uri, value[0]);
}
} else {
properties += this.writeRdf(uri, value);
}
})
})
if (!version) properties += `dct:hasVersion "undefined";\n`;
if (!version) properties += `dct:hasVersion "undefined";\n`;
return properties;
return properties;
}
publishDatasetFromGeodcatApi() {
......@@ -261,7 +264,7 @@ export class MappingComponent implements OnInit {
getKeysFromMetadataCustom(obj: Object, keyParent: string) {
Object.keys(obj).forEach(key => {
if (typeof obj[key] === 'object') {
if (Array.isArray(obj[key])) {
if (Array.isArray(obj[key])) {
obj[key].forEach(e => {
if (typeof e === 'object') {
Object.keys(e).forEach(k => {
......@@ -270,15 +273,15 @@ export class MappingComponent implements OnInit {
this.getKeysFromMetadataCustom(e, keyParent + key + ' : ');
}
});
this.keys.push(keyParent + key )
this.keys.push(keyParent + key)
this.getKeysFromMetadataCustom(obj[key], keyParent + key + ' : ');
} else {
this.keys.push(keyParent + key )
this.keys.push(keyParent + key)
this.getKeysFromMetadataCustom(obj[key], keyParent + key + ' : ');
}
} else {
this.keys.push(keyParent + key );
this.keys.push(keyParent + key);
}
});
......@@ -333,7 +336,7 @@ export class MappingComponent implements OnInit {
if (Array.isArray(obj) && obj.some(e => typeof e === 'object')) {
let array = [];
obj.forEach(e => {
if (e[tab[i]]){
if (e[tab[i]]) {
array.push(e[tab[i]]);
}
});
......@@ -342,7 +345,7 @@ export class MappingComponent implements OnInit {
let array = [];
for (let element in obj) {
obj[element].forEach(e => {
if (e[tab[i]]){
if (e[tab[i]]) {
array.push(e[tab[i]]);
}
})
......@@ -414,8 +417,8 @@ export class MappingComponent implements OnInit {
this.datasetMappedMetadatas = [];
this.distributionMappedMetadatas = [];
this.itemsdataset.forEach((dataset: Object) => {
this.datasetMappedMetadatas.push(this.createDataset(dataset, "dataset"));
this.distributionMappedMetadatas.push(this.createDataset(dataset, "distribution"))
this.datasetMappedMetadatas.push(this.createDataset(dataset, "dataset"));
this.distributionMappedMetadatas.push(this.createDataset(dataset, "distribution"))
})
console.table(this.datasetMappedMetadatas);
console.log(this.distributionMappedMetadatas);
......@@ -440,14 +443,17 @@ export class MappingComponent implements OnInit {
downloadJson() {
let datasetPathArray: DatasetPath[] = [];
for (let i = 0; i < this.dcatVocabulary.length; i++) {
for (let i = 0; i < this.datasets.length; i++) {
if (this.selectedPaths[i]) {
datasetPathArray.push(new DatasetPath(this.dcatVocabulary[i], this.selectedPaths[i]));
} else {
datasetPathArray.push(new DatasetPath(this.dcatVocabulary[i], ""));
datasetPathArray.push(new DatasetPath(this.datasets[i], this.selectedPaths[i], 'dcat:dataset'));
}
}
for (let i = 0; i < this.distributions.length; i++) {
if (this.distributionSelectedPaths[i]) {
datasetPathArray.push(new DatasetPath(this.distributions[i], this.distributionSelectedPaths[i], 'dcat:distribution'))
}
}
console.table(datasetPathArray)
/*const fileName = 'paths.json';
const fileType = this.fileSaverService.genType(fileName);
......@@ -460,58 +466,81 @@ export class MappingComponent implements OnInit {
document.getElementById('file').click();
}
fillFromTsv(vocabulary: Property[], paths: string[], tsvFile: ResponseFileTsv[], dcatClass: string) {
for (let i = 0; i < tsvFile.length; i++) {
if (i > 0 && tsvFile[i].object_id === tsvFile[i - 1].object_id) {
const voc: Property = vocabulary.find(e => e.uri === tsvFile[i].object_id);
const index = vocabulary.indexOf(voc);
vocabulary.splice(index + 1, 0, voc);
paths.splice(index + 1, 0, tsvFile[i].subject_id);
} else {
const voc: Property = vocabulary.find(e => e.uri === tsvFile[i].object_id);
const index = vocabulary.indexOf(voc);
paths[index] = tsvFile[i].subject_id;
}
}
}
importJson(event: Event) {
const files: FileList = (event.target as HTMLInputElement).files;
const jsonFile = files[0];
console.log(jsonFile)
let reader = new FileReader();
let datasetPath: DatasetPath[] | ResponseFileTsv[] = [];
const reader = new FileReader();
reader.onloadend = () => {
if (files[0].name.split('.')[1] === "tsv") {
let datasetPath: ResponseFileTsv[] = <ResponseFileTsv[]> this.mappingService.tsvToJson(reader.result as string);
let index = 0;
if (jsonFile.name.split('.')[1] === "tsv") {
let paths: ResponseFileTsv[] = <ResponseFileTsv[]>this.mappingService.tsvToJson(reader.result as string);
let datasetPath: ResponseFileTsv[] = [];
let distributionPath: ResponseFileTsv[] = [];
console.table(paths)
paths.forEach(path => {
(path.object_category.includes('dataset')) ? datasetPath.push(path) : distributionPath.push(path);
})
console.log(datasetPath)
console.log(distributionPath)
if (distributionPath.length > 0) this.addDistribution = true;
this.fillFromTsv(this.datasets, this.selectedPaths, datasetPath, 'dcat:dataset');
this.fillFromTsv(this.distributions, this.distributionSelectedPaths, distributionPath, 'dcat:distribution');
} else {
let paths: DatasetPath[] = <DatasetPath[]> JSON.parse(reader.result as string);
console.table(paths)
for (let i = 0; i < datasetPath.length; i++) {
for (let j = 0; j < this.dcatVocabulary.length; j++){
if (datasetPath[i].object_id === this.dcatVocabulary[j].uri){
if (i > 0 && datasetPath[i].object_id === datasetPath[i - 1].object_id ) {
this.selectedPaths.splice(j + 1, 0, '');
this.selectedPaths[j + 1] = datasetPath[i].subject_id;
this.dcatVocabulary[i] = this.vocabularies.find( v => v.uri === <string>datasetPath[i].object_id);
++i;
} else {
this.selectedPaths[j] = datasetPath[i].subject_id;
this.dcatVocabulary[i] = this.vocabularies.find( v => v.uri === <string>datasetPath[i].object_id);
}
for (let i = 0; i < paths.length; i++) {
if (i > 0 && paths[i].dcatProperty === paths[i - 1].dcatProperty) {
this.selectedPaths.splice(i + 1, 0, '');
this.selectedPaths[i + 1] = paths[i].path;
if (typeof paths[i].dcatProperty !== 'object') {
this.datasets[i] = this.vocabularies.filter(e => e.dcatClass === 'dcat:dataset').find(v => v.uri === <string>paths[i].dcatProperty);
} else {
this.datasets[i] = this.vocabularies.filter(e => e.dcatClass === 'dcat:dataset').find(v => v.uri === (<OldProperty><unknown>paths[i].dcatProperty).identifier);
}
}
}
} else {
let datasetPath: DatasetPath[] = <DatasetPath[]> JSON.parse(reader.result as string);
for (let i = 0; i < datasetPath.length; i++) {
this.selectedPaths[i] = datasetPath[i].path;
if (typeof datasetPath[i].dcatProperty !== 'object') {
this.dcatVocabulary[i] = this.vocabularies.filter( v => v.uri === <string>datasetPath[i].dcatProperty)[0];
} else {
this.dcatVocabulary[i] = <Property>datasetPath[i].dcatProperty;
this.selectedPaths[i] = paths[i].path;
if (typeof paths[i].dcatProperty !== 'object') {
this.datasets[i] = this.vocabularies.find(v => v.uri === <string>paths[i].dcatProperty);
} else {
this.datasets[i] = this.vocabularies.find(v => v.uri === (<OldProperty><unknown>paths[i].dcatProperty).identifier);
}
}
}
}
}
reader.readAsText(jsonFile);
}
addField(index: number) {
let addedDcat: Property = new Property(this.dcatVocabulary[index].property, this.dcatVocabulary[index].uri, this.dcatVocabulary[index].usageNote, true, this.dcatVocabulary[index].card, this.dcatVocabulary[index].geodcat);
this.dcatVocabulary.splice(index + 1, 0, addedDcat);
let addedDcat: Property = new Property(this.datasets[index].property, this.datasets[index].uri, this.datasets[index].usageNote, true, this.datasets[index].card, this.datasets[index].geodcat);
this.datasets.splice(index + 1, 0, addedDcat);
this.selectedPaths.splice(index + 1, 0, '');
console.table(this.selectedPaths)
}
deleteField(index: number) {
this.dcatVocabulary.splice(index, 1);
this.datasets.splice(index, 1);
this.selectedPaths.splice(index, 1);
console.table(this.selectedPaths)
}
......@@ -520,7 +549,7 @@ export class MappingComponent implements OnInit {
deleteProperty(key: number) {
this.datasetMappedMetadatas[this.index].delete(key);
}
trackByIndex(index: number): any {
return index;
}
......@@ -548,7 +577,7 @@ export class MappingComponent implements OnInit {
this.default = checked;
}
toggleDistri(checked: boolean){
toggleDistri(checked: boolean) {
this.addDistribution = checked;
}
......@@ -560,7 +589,7 @@ export class MappingComponent implements OnInit {
return card.endsWith("n");
}
getCard(uri:string): string {
getCard(uri: string): string {
return this.vocabularies.find((vocabulary: Property) => vocabulary.uri === uri).card;
}
......
......@@ -15,7 +15,8 @@ export class MappingService {
'subject_id',
'predicate_id',
'object_id',
'match_type'
'match_type',
'object_category'
]);
let blob = new Blob(['\ufeff' + tsvData], {
......@@ -44,7 +45,7 @@ export class MappingService {
row += headerList[index] + '\t';
}
row = row.slice(0, -1);
str += row + '\r\n';
str += row + '\n';
for (let i = 0; i < array.length; i++) {
if (array[i].path) {
......@@ -63,9 +64,12 @@ export class MappingService {
break;
case 'match_type':
line += 'lexical' + '\t';
break;
case 'object_category':
line += array[i].dcatClass + '\t';
}
}
str += line + '\r\n';
str += (i != array.length - 1) ? line + '\n' : line;
}
......
[
{
"property": "media type",
"uri": "dcat:mediaType",
"range": "dct:MediaType",
"usageNote": "This property refers to the media type of the Distribution as defined in the official register of media types managed by IANA.",
"card": "1..1",
"geodcat": false
},
{
"property": "access URL",
"uri": "dcat:accessURL",
......@@ -15,15 +23,6 @@
"card": "1..n",
"geodcat": false
},
{
"property": "media type",
"uri": "dcat:mediaType",
"range": "dct:MediaType",
"usageNote": "This property refers to the media type of the Distribution as defined in the official register of media types managed by IANA.",
"card": "1..1",
"geodcat": false
},
{
"property": "compression format",
"uri": "dcat:compressFormat",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment