diff --git a/.travis.yml b/.travis.yml index 4b3c1a0..c299f89 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ os: linux dist: xenial language: node_js node_js: - - "12" + - "14" install: - npm install - npm install -g mocha diff --git a/caracal.js b/caracal.js index 57db132..49954fd 100644 --- a/caracal.js +++ b/caracal.js @@ -18,12 +18,15 @@ const dataHandlers = require('./handlers/dataHandlers.js'); const sanitizeBody = require('./handlers/sanitizeHandler.js'); const DataSet = require('./handlers/datasetHandler.js'); const Model = require('./handlers/modelTrainer.js'); +const DataTransformationHandler = require('./handlers/dataTransformationHandler.js'); // TODO validation of data var WORKERS = process.env.NUM_THREADS || 4; var PORT = process.env.PORT || 4010; +var MONGO_URI = process.env.MONGO_URI || 'mongodb://localhost'; + const app = express(); app.use(cookieParser()); /** app.use(helmet.contentSecurityPolicy({ @@ -213,4 +216,7 @@ var startApp = function(app) { throng(WORKERS, startApp(app)); +const handler = new DataTransformationHandler(MONGO_URI, './json/configuration.json'); +handler.startHandler(); + module.exports = app; // for tests diff --git a/handlers/dataTransformationHandler.js b/handlers/dataTransformationHandler.js new file mode 100644 index 0000000..3458777 --- /dev/null +++ b/handlers/dataTransformationHandler.js @@ -0,0 +1,164 @@ +const client = require("mongodb").MongoClient; +const fs = require("fs"); + +class DataTransformationHandler { + constructor(url, path) { + this.url = url; + this.filePath = path; + this.handler = null; + this.counter = 0; + this.max = 300; + this.id = 1; + this.idLength = 6; + this.isProcessing = false; + } + + startHandler() { + console.log("||-- Start --||"); + this.counter = 0; + this.max = 300; + this.id = 1; + this.handler = setInterval(this.connect.bind(this), 10000); + } + + loadDefaultData() { + let rawdata; + let config; + try { + rawdata = fs.readFileSync(this.filePath); + config = JSON.parse(rawdata); + } catch (err) { + if (err.code == "ENOENT") { + console.log(`'${this.filePath}' File Fot Found!`); + } else { + throw err; + } + } + return config; + } + + connect() { + if (this.isProcessing) { + return; + } + if (this.counter++ == this.max) { + this.cleanHandler(); + return; + } + this.isProcessing = true; + const query = {config_name: "preset_label"}; + client + .connect(this.url, {useNewUrlParser: true}) + .then((dbc) => { + const collection = dbc.db("camic").collection("configuration"); + collection.find(query).toArray((err, rs) => { + if (err) { + this.isProcessing = false; + console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + console.log(err); + dbc.close(); + this.cleanHandler(); + return; + } + // add default data + if (rs.length < 1) { + // read default data from json + const defaultData = this.loadDefaultData(); + // insert default data + collection.insertOne(defaultData, (err, result) => { + if (err) { + this.isProcessing = false; + console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + console.log(err); + dbc.close(); + this.cleanHandler(); + return; + } + dbc.close(); + // clear handler + this.cleanHandler(); + }); + return; + } + + if (rs.length > 0 && rs[0].version != "1.0.0") { + const config = rs[0]; + const list = []; + if (config.configuration && Array.isArray(config.configuration)) { + config.configuration.forEach((node) => { + this.extractNode(node, list); + }); + } + config.configuration = list; + config.version = '1.0.0'; + if (!(list && list.length)) return; + collection.deleteOne(query, (err, result) => { + if (err) { + this.isProcessing = false; + console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + console.log(err); + dbc.close(); + this.cleanHandler(); + return; + } + collection.insertOne(config, (err, result) => { + if (err) { + this.isProcessing = false; + console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + console.log(err); + dbc.close(); + this.cleanHandler(); + return; + } + this.isProcessing = false; + console.log(`||-- The Document At The 'configuration' Collection Has Been Upgraded To Version 1.0.0 --||`); + dbc.close(); + this.cleanHandler(); + }); + }); + } + }); + }).catch((err) => { + console.log(`||-- The 'Preset Labels' Document Upgrade Is Failed --||`); + console.log(err.message); + this.isProcessing = false; + if (this.max == this.counter) { + this.cleanHandler(); + } + }); + } + extractNode(node, list) { + if (node.children && Array.isArray(node.children)) { + node.children.forEach((n) => { + this.extractNode(n, list); + }); + } + if ( + node.data && + (typeof node.data === "object" || typeof node.data === "function") && + node.data !== null + ) { + const id = zeroFill(this.id++, this.idLength); + list.push({id, ...node.data}); + } + } + + cleanHandler() { + console.log("||-- Done --||"); + this.counter = 0; + this.max = 300; + this.id = 1; + this.isProcessing = false; + clearInterval(this.handler); + } +} + +function zeroFill(number, width) { + width -= number.toString().length; + if (width > 0) { + return new Array(width + (/\./.test(number) ? 2 : 1)).join("0") + number; + } + return number + ""; +} + +module.exports = DataTransformationHandler; diff --git a/json/configuration.json b/json/configuration.json new file mode 100644 index 0000000..bed9fd3 --- /dev/null +++ b/json/configuration.json @@ -0,0 +1,196 @@ +{ + "configuration" : [ + { + "id" : "001", + "color" : "#ff6296", + "mode" : "grid", + "type" : "Lymph-Positive", + "size" : 100 + }, + { + "id" : "002", + "color" : "#ff6296", + "mode" : "point", + "type" : "Lymph-Positive" + }, + { + "id" : "003", + "color" : "#62ffcb", + "mode" : "grid", + "type" : "Lymph-Negative", + "size" : 100 + }, + { + "id" : "004", + "color" : "#62ffcb", + "mode" : "point", + "type" : "Lymph-Negative" + }, + { + "id" : "005", + "color" : "#ffcb62", + "mode" : "grid", + "type" : "Neutrophil-Positive", + "size" : 50 + }, + { + "color" : "#6296ff", + "mode" : "grid", + "type" : "Neutrophil-Negative", + "size" : 50, + "id" : "006" + }, + { + "color" : "#ff00d9", + "mode" : "grid", + "type" : "Necrosis-Positive", + "size" : 100, + "id" : "007" + }, + { + "color" : "#ff00d9", + "mode" : "grid", + "type" : "Necrosis-Positive", + "size" : 500, + "id" : "008" + }, + { + "color" : "#00ff26", + "mode" : "grid", + "type" : "Necrosis-Negative", + "size" : 100, + "id" : "009" + }, + { + "color" : "#00ff26", + "mode" : "grid", + "type" : "Necrosis-Negative", + "size" : 500, + "id" : "010" + + }, + { + "color" : "#790cff", + "mode" : "grid", + "type" : "Tumor-Positive", + "size" : 100, + "id" : "011" + }, + { + "color" : "#790cff", + "mode" : "grid", + "type" : "Tumor-Positive", + "size" : 300, + "id" : "012" + }, + { + "color" : "#790cff", + "mode" : "grid", + "type" : "Tumor-Positive", + "size" : 1000, + "id" : "013" + }, + { + "color" : "#790cff", + "mode" : "grid", + "type" : "Tumor-Positive", + "size" : 2000, + "id" : "014" + }, + { + "color" : "#92ff0c", + "mode" : "grid", + "type" : "Tumor-Negative", + "size" : 100, + "id" : "015" + }, + { + "color" : "#92ff0c", + "mode" : "grid", + "type" : "Tumor-Negative", + "size" : 300, + "id" : "016" + }, + { + "color" : "#92ff0c", + "mode" : "grid", + "type" : "Tumor-Negative", + "size" : 1000, + "id" : "017" + }, + { + "color" : "#92ff0c", + "mode" : "grid", + "type" : "Tumor-Negative", + "size" : 2000, + "id" : "018" + }, { + "color" : "#8dd3c7", + "mode" : "free", + "type" : "Prostate-Benign", + "id" : "019" + }, { + "color" : "#ffffb3", + "mode" : "free", + "type" : "Prostate-Gleason3", + "id" : "020" + }, { + "color" : "#bebada", + "mode" : "free", + "type" : "Prostate-Gleason4", + "id" : "021" + }, { + "color" : "#fb8072", + "mode" : "free", + "type" : "Prostate-Gleason5", + "id" : "022" + }, { + "color" : "#80b1d3", + "mode" : "free", + "type" : "Prostate-CancerNOS", + "id" : "023" + }, { + "color" : "#fdb462", + "mode" : "free", + "type" : "NSCLC-Benign", + "id" : "024" + }, { + "color" : "#b3de69", + "mode" : "free", + "type" : "NSCLC-SquamousCA", + "id" : "025" + }, { + "color" : "#fccde5", + "mode" : "free", + "type" : "NSCLC-AdenoCA(all)", + "id" : "026" + }, { + "color" : "#d9d9d9", + "mode" : "free", + "type" : "NSCLC-Acinar", + "id" : "027" + }, { + "color" : "#bc80bd", + "mode" : "free", + "type" : "NSCLC-Lapidic", + "id" : "028" + }, { + "color" : "#ccebc5", + "mode" : "free", + "type" : "NSCLC-Solid", + "id" : "029" + }, { + "color" : "#ffed6f", + "mode" : "free", + "type" : "NSCLC-Papillary", + "id" : "030" + }, { + "color" : "#6a3d9a", + "mode" : "free", + "type" : "NSCLC-Micropapillary", + "id" : "031" + } + ], + "config_name" : "preset_label", + "version" : "1.0.0" +} \ No newline at end of file