UNPKG

modified-dicom-pacs

Version:

A modified version of DICOM PACS implementation

466 lines (418 loc) 13.5 kB
// const config = require('config'); const config = require('../config/default'); const dict = require('dicom-data-dictionary'); const dimse = require('dicom-dimse-native'); const fs = require('fs'); const shell = require('shelljs'); const path = require('path'); const sqlite3 = require('sqlite3').verbose(); let sql; let baseDir = path.resolve(__dirname.split('webpacsApp')[0]); // // open database in memory // console.log("path=-=", path.join(__dirname, '../../../database.sqlite3')); // let databaseFile = path.join(baseDir, 'database.sqlite3'); let mainUrl = 'D:/markematics/work.hassaan/projects/react practice/OfficeTry/Helical-version2'; let databaseFile = `${mainUrl}/database.sqlite3`; //connect to db let db = new sqlite3.Database(databaseFile, sqlite3.OPEN_READWRITE, (err) => { if (err) { return console.error('line 11 database err', err.message); } console.log('Connected to the in-memory SQlite database.'); }); //create table // sql = 'CREATE TABLE PACSNODE(aet,ip,port)'; // db.run(sql); // insert into database // db.run(`INSERT INTO PACSNODE(aet,ip,port) VALUES(?,?,?)`, ['myaet', 'myip', 'myport'], function(err) { // if (err) { // return console.log("line 26 database err",err.message); // } // // get the last insert id // console.log(`A row has been inserted`); // }); // read data from database // sql = `SELECT * FROM PACSNODE`; // db.all(sql, [], (err, rows) => { // if(err) return console.error("line 44 database error", err.message); // rows.forEach((row) => { // console.log("rowwwwwwwwwwwwwww", row); // }); // }) //'../../../data/Native/Incoming' // make sure default directories exist // const logDir = config.get('logDir'); const logDir = config.logDir; shell.mkdir('-p', logDir); shell.mkdir('-p', config.storagePath); // create a rolling file logger based on date/time that fires process events const opts = { errorEventName: 'error', logDirectory: logDir, // NOTE: folder must exist and be writable... fileNamePattern: 'roll-<DATE>.log', dateFormat: 'YYYY.MM.DD', }; const manager = require('simple-node-logger').createLogManager(); // manager.createConsoleAppender(); manager.createRollingFileAppender(opts); const logger = manager.createLogger(); //------------------------------------------------------------------ const findDicomName = (name) => { // eslint-disable-next-line no-restricted-syntax for (const key of Object.keys(dict.standardDataElements)) { const value = dict.standardDataElements[key]; if (value.name === name) { return key; } } return undefined; }; //working on database starts //working on database starts //------------------------------------------------------------------ const utils = { getLogger: () => logger, startScp: () => { // read data from database let source = {}; var enable = true; var defaultIP; // sql = `SELECT * FROM PacsSetup`; // db.all(sql, [], (err, rows) => { // if (err) return console.error('line 34 database error', err.message); // enable = rows[0]['enable']; // }); sql = `SELECT * FROM sourceNode where enable = "true"`; db.all(sql, [], (err, rows) => { if (err) return console.error('line 34 database error', err.message); console.log('sourceee db read', rows); source = rows[rows.length - 1]; }); //database work ends setTimeout(() => { console.log('j.source', source); // const source = config.get('source'); // const source = { aet: "DICOMWEB_PACS1", ip: "192.168.18.23", port: "5558" }; // const ar = config.get('peers'); // const ar = config.peers; const peers = []; // ar.forEach((aet) => { // peers.push(aet); // }); // const ts = config.get('transferSyntax'); const ts = config.transferSyntax; const j = {}; j.source = source; j.target = j.source; j.peers = peers; j.peers.push(j.source); //database work srats // read data from database sql = `SELECT * FROM PACSNODE`; db.all(sql, [], (err, rows) => { if (err) return console.error('line 44 database error', err.message); rows.forEach((row) => { console.log('scp', row, row.aet); j.peers.push({ aet: row.aet, ip: row.ip, port: row.port, }); if (enable == 'false') { console.log('ura do peers'); j.peers = []; } // console.log(j.peers,localStorage,"j.peers") }); }); //database work ends // j.peers.push({ // aet: "DICOMWEB_PA1", // // ip: "192.168.100.20", // // port: "9991" // }) // j.peers.push({ // aet: "DICOMWEB_PA2", // // ip: "192.168.100.20", // // port: "9991" // }) // j.peers.push({ // aet: "DICOMWEB_PA3", // // ip: "192.168.100.20", // // port: "9991" // }) // j.peers.push({ // aet: "DICOMWEB_PA4", // // ip: "192.168.100.20", // // port: "9991" // }) // j.peers.push({ // aet: "DICOMWEB_PA5", // // ip: "192.168.100.20", // // port: "9991" // }) // j.peers.push({ // aet: "DICOMWEB_PA6", // // ip: "192.168.100.20", // // port: "9991" // }) // j.peers.push({ // aet: "DICOMWEB_PA7", // // ip: "192.168.100.20", // // port: "9991" // }) setTimeout(() => { // j.storagePath = config.get('storagePath'); j.storagePath = config.storagePath; j.verbose = config.verboseLogging; j.permissive = config.permissiveMode; j.netTransferPrefer = ts; j.netTransferPropose = ts; j.writeTransfer = ts; logger.info(`pacs-server listening on port: ${j.source.port}`); dimse.startStoreScp(j, (result) => { // currently this will never finish logger.info(JSON.parse(result)); }); }, 2000); }, 1000); }, shutdown: () => { const j = {}; let source = {}; // read data from database sql = `SELECT * FROM sourceNode where enable = "true"`; db.all(sql, [], (err, rows) => { if (err) return console.error('line 34 database error', err.message); console.log('sourceee db read', rows[rows.length - 1]); source = rows[rows.length - 1]; }); //database work ends setTimeout(() => { j.source = source; // j.target = source; // j.source = config.get('source'); // j.target = config.get('source'); // j.source = { aet: "DICOMWEB_PACS1", ip: "192.168.18.23", port: "5558" }; // j.target = { aet: "DICOMWEB_PACS1", ip: "192.168.18.23", port: "5558" }; j.verbose = config.verboseLogging; logger.info(`sending shutdown request to target: ${j.target.aet}`); return new Promise((resolve, reject) => { dimse.shutdownScu(j, (result) => { if (result && result.length > 0) { try { logger.info(JSON.parse(result)); resolve(); } catch (error) { logger.error(result); reject(); } } reject(); }); }); }, 1000); }, sendEcho: () => { const j = {}; // j.source = config.get('source'); // read data from database sql = `SELECT * FROM sourceNode where enable = "true"`; db.all(sql, [], (err, rows) => { if (err) return console.error('line 34 database error', err.message); console.log('sourceee db read', rows[rows.length - 1]); j.source = rows[rows.length - 1]; }); //database work ends setTimeout(() => { console.log('j.source', j.source); //j.source = { aet: "DICOMWEB_PACS1", ip: "192.168.18.23", port: "5558" }; // { aet: "DICOMWEB_PACS1", ip: "192.168.18.23", port: "5558" } j.target = j.source; j.verbose = config.verboseLogging; console.log('echoooooooooooooooooooooooooo'); logger.info(`sending C-ECHO to target: ${j.target.aet}`); return new Promise((resolve, reject) => { dimse.echoScu(j, (result) => { if (result && result.length > 0) { try { logger.info(JSON.parse(result)); resolve(); } catch (error) { logger.error(result); reject(); } } reject(); }); }); }, 1000); }, fileExists: (pathname) => new Promise((resolve, reject) => { fs.access(pathname, (err) => { if (err) { reject(err); } else { resolve(); } }); }), studyLevelTags: () => [ '00080005', '00080020', '00080030', '00080050', '00080054', '00080056', '00080061', '00080090', '00081190', '00100010', '00100020', '00100030', '00100040', '0020000D', '00200010', '00201206', '00201208', ], seriesLevelTags: () => ['00080005', '00080054', '00080056', '00080060', '0008103E', '00081190', '0020000E', '00200011', '00201209'], imageLevelTags: () => ['00080016', '00080018'], imageMetadataTags: () => [ '00080016', '00080018', '00080060', '00280002', '00280004', '00280010', '00280011', '00280030', '00280100', '00280101', '00280102', '00280103', '00281050', '00281051', '00281052', '00281053', '00200032', '00200037', ], compressFile: (inputFile, outputDirectory, transferSyntax) => { const j = { sourcePath: inputFile, storagePath: outputDirectory, writeTransfer: transferSyntax || config.transferSyntax, verbose: config.verboseLogging, }; // run find scu and return json response return new Promise((resolve, reject) => { dimse.recompress(j, (result) => { if (result && result.length > 0) { try { const json = JSON.parse(result); if (json.code === 0) { resolve(); } else { logger.error(`recompression failure (${inputFile}): ${json.message}`); reject(); } } catch (error) { logger.error(error); logger.error(result); reject(); } } else { logger.error('invalid result received'); reject(); } }); }); }, doFind: (queryLevel, query, defaults) => { // add query retrieve level const j = { tags: [ { key: '00080052', value: queryLevel, }, ], }; // set source and target from config // j.source = config.get('source'); // j.source = config.get('source'); j.source = { aet: 'DICOMWEB_PACS1', ip: '192.168.18.23', port: '5558' }; j.target = j.source; j.verbose = config.verboseLogging; // parse all include fields const includes = query.includefield; let tags = []; if (includes) { tags = includes.split(','); } tags.push(...defaults); // add parsed tags tags.forEach((element) => { const tagName = findDicomName(element) || element; j.tags.push({ key: tagName, value: '' }); }); // add search param let isValidInput = false; Object.keys(query).forEach((propName) => { const tag = findDicomName(propName); if (tag) { let v = query[propName]; // patient name check if (tag === '00100010') { // check if minimum number of chars for patient name are given if (config.qidoMinChar > v.length) { isValidInput = true; } // auto append wildcard if (config.qidoAppendWildcard) { v += '*'; } } j.tags.push({ key: tag, value: v }); } }); // return with empty results if invalid if (isValidInput) { return []; } const offset = query.offset ? parseInt(query.offset, 10) : 0; // run find scu and return json response return new Promise((resolve) => { dimse.findScu(j, (result) => { if (result && result.length > 0) { try { const json = JSON.parse(result); if (json.code === 0) { const container = JSON.parse(json.container); if (container) { resolve(container.slice(offset)); } else { resolve([]); } } else if (json.code === 1) { logger.info('query is pending...'); } else { logger.error(`c-find failure: ${json.message}`); resolve([]); } } catch (error) { logger.error(error); logger.error(result); resolve([]); } } else { logger.error('invalid result received'); resolve([]); } }); }); }, }; module.exports = utils;