@igea/oac_backend 1.0.18 → 1.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/controllers/fuseki.js +84 -0
- package/src/data/import/readme.md +1 -0
- package/src/index.js +3 -1
- package/src/models/vocabolaries/parser +13 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@igea/oac_backend",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.19",
|
|
4
4
|
"description": "Backend service for the OAC project",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"get-port": "7.1.0",
|
|
27
27
|
"knex": "3.1.0",
|
|
28
28
|
"libxmljs2": "0.37.0",
|
|
29
|
+
"multer": "2.0.2",
|
|
29
30
|
"pg": "8.16.3",
|
|
30
31
|
"strip-bom": "5.0.0"
|
|
31
32
|
},
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
|
+
const multer = require('multer');
|
|
2
3
|
const router = express.Router();
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
3
6
|
const config = require('../config')
|
|
4
7
|
const configFuseki = config.fuseki || {
|
|
5
8
|
"protocol": "http",
|
|
@@ -10,7 +13,88 @@ const configFuseki = config.fuseki || {
|
|
|
10
13
|
const fusekiUrl = `${configFuseki.protocol}://${configFuseki.host}:${configFuseki.port}/${configFuseki.dataset}/sparql`;
|
|
11
14
|
const axios = require('axios');
|
|
12
15
|
const Fuseki = require('../models/fuseki');
|
|
16
|
+
const VocabParser = require('../models/vocabolaries/parser').GET_INSTANCE();
|
|
13
17
|
|
|
18
|
+
//---------------------------------------------------------------
|
|
19
|
+
const uploadFolder = path.join(__dirname, '../data/import');
|
|
20
|
+
if (!fs.existsSync(uploadFolder)) {
|
|
21
|
+
fs.mkdirSync(uploadFolder);
|
|
22
|
+
}
|
|
23
|
+
const uploadStorage = multer.diskStorage({
|
|
24
|
+
destination: (req, file, cb) => {
|
|
25
|
+
cb(null, uploadFolder); // Folder where files will be stored
|
|
26
|
+
},
|
|
27
|
+
filename: (req, file, cb) => {
|
|
28
|
+
cb(null, Date.now() + '-' + file.originalname);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const upload = multer({ storage: uploadStorage });
|
|
33
|
+
const deleteFiles = function(files){
|
|
34
|
+
for(let i=0; i<files.length; i++){
|
|
35
|
+
fs.unlink(files[i].path, (err) => {
|
|
36
|
+
if (err) {
|
|
37
|
+
console.error('Error deleting file:', files[i].path, err);
|
|
38
|
+
} else {
|
|
39
|
+
console.log('File deleted successfully:', files[i].path);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Route to upload vocabulary files
|
|
46
|
+
* @route POST /fuseki/upload/vocabularies
|
|
47
|
+
* @param {Array} files - Array of files to be uploaded
|
|
48
|
+
* @returns {Object} - Response object with message and file details
|
|
49
|
+
*
|
|
50
|
+
* curl -X POST -F "files=@vocabolaries.xsd" http://localhost:5000/backend/fuseki/upload/vocabularies
|
|
51
|
+
*
|
|
52
|
+
* */
|
|
53
|
+
router.post('/upload/vocabularies', upload.array('files'), (req, res) => {
|
|
54
|
+
if (!req.files || req.files.length === 0) {
|
|
55
|
+
return res.status(400).json({ message: 'No file uploaded' });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const uploadedFiles = req.files.map(file => ({
|
|
59
|
+
filename: file.filename,
|
|
60
|
+
originalname: file.originalname,
|
|
61
|
+
mimetype: file.mimetype,
|
|
62
|
+
size: file.size,
|
|
63
|
+
path: file.path
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
const xmlFiles = uploadedFiles.filter(f => f.mimetype === 'application/xml' || f.mimetype === 'text/xml')
|
|
67
|
+
.map(file => file.valid = VocabParser.validate(file.path).status)
|
|
68
|
+
|
|
69
|
+
if(xmlFiles.length == 1) {
|
|
70
|
+
let xmlFile = uploadedFiles[0];
|
|
71
|
+
VocabParser.transform(xmlFile.path).then(terms => {
|
|
72
|
+
console.log(terms)
|
|
73
|
+
deleteFiles(uploadedFiles)
|
|
74
|
+
res.json({
|
|
75
|
+
message: 'File correctly uploaded',
|
|
76
|
+
files: uploadedFiles
|
|
77
|
+
});
|
|
78
|
+
}).catch(err => {
|
|
79
|
+
deleteFiles(uploadedFiles)
|
|
80
|
+
console.error('Error transforming XML:', err);
|
|
81
|
+
res.status(500).json({
|
|
82
|
+
message: 'Error transforming XML:' + err.message,
|
|
83
|
+
files: uploadedFiles
|
|
84
|
+
});
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
}else{
|
|
88
|
+
deleteFiles(uploadedFiles);
|
|
89
|
+
let message = 'Multiple XML files is not supported';
|
|
90
|
+
if(xmlFiles.length == 0)
|
|
91
|
+
message = 'No XML files uploaded';
|
|
92
|
+
return res.status(400).json({ message });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
//---------------------------------------------------------------
|
|
14
98
|
router.get('/count/entities', (req, res) => {
|
|
15
99
|
const query = `
|
|
16
100
|
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
This folder contains data uploaded (temporary)
|
package/src/index.js
CHANGED
|
@@ -10,7 +10,9 @@ const jwtLib = jwtLibFactory({
|
|
|
10
10
|
excludePaths: [
|
|
11
11
|
`/${serviceName}/auth/authenticate`,
|
|
12
12
|
`/${serviceName}/auth/echo`,
|
|
13
|
-
`/${serviceName}/health
|
|
13
|
+
`/${serviceName}/health`,
|
|
14
|
+
`/${serviceName}/fuseki/upload/vocabularies`
|
|
15
|
+
|
|
14
16
|
],
|
|
15
17
|
signOptions: { expiresIn: '15m' }
|
|
16
18
|
});
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const XsltProcessor = require('xslt-processor');
|
|
4
|
-
const {XmlParser, Xslt} = XsltProcessor;
|
|
5
3
|
const libxmljs = require('libxmljs2');
|
|
6
4
|
const { exec } = require('child_process');
|
|
7
5
|
const stripBom = require('strip-bom').default;
|
|
@@ -39,6 +37,19 @@ class Parser{
|
|
|
39
37
|
return xmlDoc;
|
|
40
38
|
}
|
|
41
39
|
|
|
40
|
+
validate(xmlPath){
|
|
41
|
+
let result = {
|
|
42
|
+
status: true, message: ''
|
|
43
|
+
};
|
|
44
|
+
try{
|
|
45
|
+
this.parse(xmlPath);
|
|
46
|
+
}catch(e){
|
|
47
|
+
result.status = false;
|
|
48
|
+
result.message = `XML validation failed: ${e.message}`;
|
|
49
|
+
}
|
|
50
|
+
return result
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
transform(xmlPath){
|
|
43
54
|
return new Promise((resolve, reject) => {
|
|
44
55
|
try{
|