LT-67; OHIF-78: Merging server configuration and CINE dialog changes from downstream (Ascend)
This commit is contained in:
parent
da7202de0f
commit
8d5d1ee360
@ -1,3 +1,4 @@
|
|||||||
|
accounts-base@1.2.11
|
||||||
aldeed:simple-schema@1.5.3
|
aldeed:simple-schema@1.5.3
|
||||||
aldeed:template-extension@4.0.0
|
aldeed:template-extension@4.0.0
|
||||||
allow-deny@1.0.5
|
allow-deny@1.0.5
|
||||||
@ -24,6 +25,7 @@ cornerstone@0.0.1
|
|||||||
ddp@1.2.5
|
ddp@1.2.5
|
||||||
ddp-client@1.3.1
|
ddp-client@1.3.1
|
||||||
ddp-common@1.2.6
|
ddp-common@1.2.6
|
||||||
|
ddp-rate-limiter@1.0.5
|
||||||
ddp-server@1.3.10
|
ddp-server@1.3.10
|
||||||
deps@1.0.12
|
deps@1.0.12
|
||||||
design@0.0.1
|
design@0.0.1
|
||||||
@ -51,6 +53,7 @@ johdirr:meteor-git-rev@0.0.4
|
|||||||
jquery@1.11.9
|
jquery@1.11.9
|
||||||
launch-screen@1.0.12
|
launch-screen@1.0.12
|
||||||
livedata@1.0.18
|
livedata@1.0.18
|
||||||
|
localstorage@1.0.11
|
||||||
logging@1.1.15
|
logging@1.1.15
|
||||||
mdg:validation-error@0.5.1
|
mdg:validation-error@0.5.1
|
||||||
meteor@1.2.17
|
meteor@1.2.17
|
||||||
@ -78,12 +81,14 @@ practicalmeteor:chai@2.1.0_1
|
|||||||
practicalmeteor:loglevel@1.2.0_2
|
practicalmeteor:loglevel@1.2.0_2
|
||||||
promise@0.8.7
|
promise@0.8.7
|
||||||
random@1.0.10
|
random@1.0.10
|
||||||
|
rate-limit@1.0.5
|
||||||
reactive-dict@1.1.8
|
reactive-dict@1.1.8
|
||||||
reactive-var@1.0.10
|
reactive-var@1.0.10
|
||||||
reload@1.1.10
|
reload@1.1.10
|
||||||
retry@1.0.8
|
retry@1.0.8
|
||||||
routepolicy@1.0.11
|
routepolicy@1.0.11
|
||||||
rwatts:uuid@0.1.0
|
rwatts:uuid@0.1.0
|
||||||
|
service-configuration@1.0.10
|
||||||
session@1.1.6
|
session@1.1.6
|
||||||
shell-server@0.2.1
|
shell-server@0.2.1
|
||||||
silentcicero:jszip@0.0.4
|
silentcicero:jszip@0.0.4
|
||||||
|
|||||||
@ -11,19 +11,36 @@
|
|||||||
Open Health Imaging Foundation
|
Open Health Imaging Foundation
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
{{ #if studyListToggleText }}
|
{{#if studyListToggleText}}
|
||||||
<a class="btn studyListLinkSection pull-left m-x-1 p-x-2 p-y-0 js-toggle-studyList">
|
<a class="btn studyListLinkSection pull-left m-x-1 p-x-2 p-y-0 js-toggle-studyList">
|
||||||
{{studyListToggleText}}
|
{{studyListToggleText}}
|
||||||
</a>
|
</a>
|
||||||
{{ /if }}
|
{{/if}}
|
||||||
<a class="btn pull-right p-y-0"
|
<span class="pull-right">
|
||||||
data-toggle="modal"
|
<div class="dropdown">
|
||||||
data-target="#aboutModal">
|
<div class="dropdown-toggle noselect clearfix" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
About
|
<span class="pull-left m-r-1">Options</span>
|
||||||
|
<div class="menuButton pull-right"><span class="caret-down"></span></div>
|
||||||
|
</div>
|
||||||
|
<ul class="dropdown-menu dropdown-menu-right">
|
||||||
|
<li>
|
||||||
|
<a data-toggle="modal" data-target="#serverInformationModal">
|
||||||
|
<i class="fa fa-server fa-lg"></i> Server Information
|
||||||
</a>
|
</a>
|
||||||
|
</li>
|
||||||
|
<li role="separator" class="divider"></li>
|
||||||
|
<li>
|
||||||
|
<a data-toggle="modal" data-target="#aboutModal">
|
||||||
|
<i class="fa fa-info"></i> About
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{> worklist }}
|
{{>serverInformationModal}}
|
||||||
{{> aboutModal }}
|
{{>worklist}}
|
||||||
{{> viewSeriesDetailsModal }}
|
{{>aboutModal}}
|
||||||
|
{{>viewSeriesDetailsModal}}
|
||||||
</template>
|
</template>
|
||||||
@ -1,3 +1,6 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Session } from 'meteor/session';
|
||||||
|
|
||||||
const worklistContentId = 'worklistTab';
|
const worklistContentId = 'worklistTab';
|
||||||
let lastContentId;
|
let lastContentId;
|
||||||
|
|
||||||
|
|||||||
@ -221,6 +221,10 @@ Template.toolbarSection.onRendered(function() {
|
|||||||
|
|
||||||
instance.$('#layout').dropdown();
|
instance.$('#layout').dropdown();
|
||||||
|
|
||||||
|
if (OHIF.uiSettings.showCineDialogOnRendered) {
|
||||||
|
toggleCineDialog();
|
||||||
|
}
|
||||||
|
|
||||||
// Set disabled/enabled tool buttons that are set in toolManager
|
// Set disabled/enabled tool buttons that are set in toolManager
|
||||||
const states = toolManager.getToolDefaultStates();
|
const states = toolManager.getToolDefaultStates();
|
||||||
const disabledToolButtons = states.disabledToolButtons;
|
const disabledToolButtons = states.disabledToolButtons;
|
||||||
|
|||||||
@ -31,6 +31,9 @@ label.form-group
|
|||||||
margin-left: auto
|
margin-left: auto
|
||||||
margin-right: auto
|
margin-right: auto
|
||||||
|
|
||||||
|
.height-auto
|
||||||
|
height: auto !important
|
||||||
|
|
||||||
.caret-down
|
.caret-down
|
||||||
display: inline-block
|
display: inline-block
|
||||||
width: 0
|
width: 0
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
|
||||||
// Uses NodeJS 'net'
|
// Uses NodeJS 'net'
|
||||||
// https://nodejs.org/api/net.html
|
// https://nodejs.org/api/net.html
|
||||||
var net = Npm.require('net'),
|
var net = Npm.require('net');
|
||||||
Socket = net.Socket;
|
var Socket = net.Socket;
|
||||||
|
|
||||||
var DEFAULT_MAX_PACKAGE_SIZE = 32768;
|
|
||||||
|
|
||||||
Connection = function(options) {
|
Connection = function(options) {
|
||||||
EventEmitter.call(this);
|
EventEmitter.call(this);
|
||||||
@ -16,10 +16,7 @@ Connection = function(options) {
|
|||||||
}
|
}
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
this.peers = {};
|
this.reset();
|
||||||
this.peerSockets = {};
|
|
||||||
this.defaultPeer = null;
|
|
||||||
this.defaultServer = null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
util.inherits(Connection, EventEmitter);
|
util.inherits(Connection, EventEmitter);
|
||||||
@ -30,15 +27,29 @@ var StoreHandle = function() {
|
|||||||
|
|
||||||
util.inherits(StoreHandle, EventEmitter);
|
util.inherits(StoreHandle, EventEmitter);
|
||||||
|
|
||||||
|
Connection.prototype.reset = function() {
|
||||||
|
this.defaultPeer = null;
|
||||||
|
this.defaultServer = null;
|
||||||
|
|
||||||
|
_.each(this.peers, peerInfo => {
|
||||||
|
_.each(peerInfo.sockets, socket => socket.emit('close'));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.peers = {};
|
||||||
|
};
|
||||||
|
|
||||||
Connection.prototype.addPeer = function(options) {
|
Connection.prototype.addPeer = function(options) {
|
||||||
if (!options.aeTitle || !options.host || !options.port) {
|
if (!options.aeTitle || !options.host || !options.port) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.peers[options.aeTitle] = {
|
var peer = {
|
||||||
host: options.host,
|
host: options.host,
|
||||||
port: options.port
|
port: options.port,
|
||||||
|
sockets: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.peers[options.aeTitle] = peer;
|
||||||
if (options.default) {
|
if (options.default) {
|
||||||
if (options.server) {
|
if (options.server) {
|
||||||
this.defaultServer = options.aeTitle;
|
this.defaultServer = options.aeTitle;
|
||||||
@ -49,22 +60,21 @@ Connection.prototype.addPeer = function(options) {
|
|||||||
|
|
||||||
if (options.server) {
|
if (options.server) {
|
||||||
//start listening
|
//start listening
|
||||||
var server = net.createServer();
|
peer.server = net.createServer();
|
||||||
server.listen(options.port, options.host, function() {
|
peer.server.listen(options.port, options.host, function() {
|
||||||
console.log('listening on %j', this.address());
|
console.log('listening on %j', this.address());
|
||||||
});
|
});
|
||||||
server.on('error', function(err) {
|
peer.server.on('error', function(err) {
|
||||||
console.log('server error %j', err);
|
console.log('server error %j', err);
|
||||||
});
|
});
|
||||||
var o = this;
|
peer.server.on('connection', nativeSocket => {
|
||||||
server.on('connection', function(nativeSocket) {
|
|
||||||
//incoming connections
|
//incoming connections
|
||||||
var socket = new CSocket(nativeSocket, o.options);
|
var socket = new CSocket(nativeSocket, this.options);
|
||||||
o.addSocket(options.aeTitle, socket);
|
this.addSocket(options.aeTitle, socket);
|
||||||
|
|
||||||
//close server on close socket
|
//close server on close socket
|
||||||
socket.on('close', function() {
|
socket.on('close', function() {
|
||||||
server.close();
|
peer.server.close();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -81,8 +91,8 @@ Connection.prototype.selectPeer = function(aeTitle) {
|
|||||||
Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLength, list) {
|
Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLength, list) {
|
||||||
var fileNameText = typeof file.file === 'string' ? file.file : 'buffer';
|
var fileNameText = typeof file.file === 'string' ? file.file : 'buffer';
|
||||||
console.log('Sending file ' + fileNameText);
|
console.log('Sending file ' + fileNameText);
|
||||||
var useContext = socket.getContextByUID(file.context),
|
var useContext = socket.getContextByUID(file.context);
|
||||||
self = this;
|
var self = this;
|
||||||
|
|
||||||
PDU.generatePDatas(useContext.id, file.file, maxSend, null, metaLength, function(err, handle) {
|
PDU.generatePDatas(useContext.id, file.file, maxSend, null, metaLength, function(err, handle) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -122,13 +132,14 @@ Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLe
|
|||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.storeInstances = function(fileList) {
|
Connection.prototype.storeInstances = function(fileList) {
|
||||||
var contexts = {},
|
var contexts = {};
|
||||||
read = 0,
|
var read = 0;
|
||||||
length = fileList.length,
|
var length = fileList.length;
|
||||||
toSend = [],
|
var toSend = [];
|
||||||
self = this,
|
var self = this;
|
||||||
handle = new StoreHandle();
|
var handle = new StoreHandle();
|
||||||
var lastProcessedMetaLength;
|
var lastProcessedMetaLength;
|
||||||
|
|
||||||
fileList.forEach(function(bufferOrFile) {
|
fileList.forEach(function(bufferOrFile) {
|
||||||
var fileNameText = typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer';
|
var fileNameText = typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer';
|
||||||
DicomMessage.readMetaHeader(bufferOrFile, function(err, metaMessage, metaLength) {
|
DicomMessage.readMetaHeader(bufferOrFile, function(err, metaMessage, metaLength) {
|
||||||
@ -144,9 +155,9 @@ Connection.prototype.storeInstances = function(fileList) {
|
|||||||
|
|
||||||
console.log('Dicom file ' + (typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer') + ' found');
|
console.log('Dicom file ' + (typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer') + ' found');
|
||||||
lastProcessedMetaLength = metaLength;
|
lastProcessedMetaLength = metaLength;
|
||||||
var syntax = metaMessage.getValue(0x00020010),
|
var syntax = metaMessage.getValue(0x00020010);
|
||||||
sopClassUID = metaMessage.getValue(0x00020002),
|
var sopClassUID = metaMessage.getValue(0x00020002);
|
||||||
instanceUID = metaMessage.getValue(0x00020003);
|
var instanceUID = metaMessage.getValue(0x00020003);
|
||||||
|
|
||||||
if (!contexts[sopClassUID]) {
|
if (!contexts[sopClassUID]) {
|
||||||
contexts[sopClassUID] = [];
|
contexts[sopClassUID] = [];
|
||||||
@ -173,23 +184,22 @@ Connection.prototype.storeInstances = function(fileList) {
|
|||||||
// Starts to send dcm files
|
// Starts to send dcm files
|
||||||
sendProcessedFiles = function(self, contexts, toSend, handle, metaLength) {
|
sendProcessedFiles = function(self, contexts, toSend, handle, metaLength) {
|
||||||
var useContexts = [];
|
var useContexts = [];
|
||||||
for (var context in contexts) {
|
_.each(contexts, (useSyntaxes, context) => {
|
||||||
var useSyntaxes = contexts[context];
|
|
||||||
if (useSyntaxes.length > 0) {
|
if (useSyntaxes.length > 0) {
|
||||||
useContexts.push({
|
useContexts.push({
|
||||||
context: context,
|
context: context,
|
||||||
syntaxes: contexts[context]
|
syntaxes: useSyntaxes
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw 'No syntax specified for context ' + context;
|
throw 'No syntax specified for context ' + context;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
self.associate({
|
self.associate({
|
||||||
contexts: useContexts
|
contexts: useContexts
|
||||||
}, function(ac) {
|
}, function(ac) {
|
||||||
var maxSend = ac.getMaxSize(),
|
var maxSend = ac.getMaxSize();
|
||||||
next = toSend.shift();
|
var next = toSend.shift();
|
||||||
self._sendFile(this, handle, next, maxSend, metaLength, toSend);
|
self._sendFile(this, handle, next, maxSend, metaLength, toSend);
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -202,8 +212,8 @@ Connection.prototype.storeResponse = function(messageId, msg) {
|
|||||||
var status = rq.listener[2].call(this, msg);
|
var status = rq.listener[2].call(this, msg);
|
||||||
if (status !== undefined && status !== null && rq.command.store) {
|
if (status !== undefined && status !== null && rq.command.store) {
|
||||||
//store ok, ready to send c-store-rsp
|
//store ok, ready to send c-store-rsp
|
||||||
var storeSr = rq.command.store,
|
var storeSr = rq.command.store;
|
||||||
replyMessage = storeSr.replyWith(status);
|
var replyMessage = storeSr.replyWith(status);
|
||||||
replyMessage.setAffectedSOPInstanceUID(this.lastCommand.getSOPInstanceUID());
|
replyMessage.setAffectedSOPInstanceUID(this.lastCommand.getSOPInstanceUID());
|
||||||
replyMessage.setReplyMessageId(this.lastCommand.messageId);
|
replyMessage.setReplyMessageId(this.lastCommand.messageId);
|
||||||
this.sendMessage(replyMessage, null, null, storeSr);
|
this.sendMessage(replyMessage, null, null, storeSr);
|
||||||
@ -215,8 +225,8 @@ Connection.prototype.storeResponse = function(messageId, msg) {
|
|||||||
|
|
||||||
Connection.prototype.allClosed = function() {
|
Connection.prototype.allClosed = function() {
|
||||||
var allClosed = true;
|
var allClosed = true;
|
||||||
for (var i in o.peerSockets) {
|
for (var i in this.peers) {
|
||||||
if (Object.keys(o.peerSockets[ae]).length > 0) {
|
if (Object.keys(peers[i].sockets).length > 0) {
|
||||||
allClosed = false;
|
allClosed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -225,34 +235,30 @@ Connection.prototype.allClosed = function() {
|
|||||||
return allClosed;
|
return allClosed;
|
||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.addSocket = function(ae, socket) {
|
Connection.prototype.addSocket = function(hostAE, socket) {
|
||||||
if (!this.peerSockets[ae]) {
|
var peerInfo = this.selectPeer(hostAE);
|
||||||
this.peerSockets[ae] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
this.peerSockets[ae][socket.id] = socket;
|
peerInfo.sockets[socket.id] = socket;
|
||||||
|
|
||||||
var o = this;
|
|
||||||
socket.on('close', function() {
|
socket.on('close', function() {
|
||||||
if (o.peerSockets[ae][this.id]) {
|
if (peerInfo.sockets[this.id]) {
|
||||||
delete o.peerSockets[ae][this.id];
|
delete peerInfo.sockets[this.id];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.associate = function(options, callback) {
|
Connection.prototype.associate = function(options, callback) {
|
||||||
var hostAE = options.hostAE ? options.hostAE : this.defaultPeer,
|
var hostAE = options.hostAE ? options.hostAE : this.defaultPeer;
|
||||||
sourceAE = options.sourceAE ? options.sourceAE : this.defaultServer;
|
var sourceAE = options.sourceAE ? options.sourceAE : this.defaultServer;
|
||||||
|
|
||||||
if (!hostAE || !sourceAE) {
|
if (!hostAE || !sourceAE) {
|
||||||
throw 'Peers not provided or no defaults in settings';
|
throw 'Peers not provided or no defaults in settings';
|
||||||
}
|
}
|
||||||
|
|
||||||
var peerInfo = this.selectPeer(hostAE),
|
var peerInfo = this.selectPeer(hostAE);
|
||||||
nativeSocket = new Socket();
|
var nativeSocket = new Socket();
|
||||||
|
|
||||||
var socket = new CSocket(nativeSocket, this.options),
|
var socket = new CSocket(nativeSocket, this.options);
|
||||||
o = this;
|
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
socket.once('associated', callback);
|
socket.once('associated', callback);
|
||||||
@ -268,9 +274,9 @@ Connection.prototype.associate = function(options, callback) {
|
|||||||
nativeSocket.connect({
|
nativeSocket.connect({
|
||||||
host: peerInfo.host,
|
host: peerInfo.host,
|
||||||
port: peerInfo.port
|
port: peerInfo.port
|
||||||
}, function() {
|
}, () => {
|
||||||
//connected
|
//connected
|
||||||
o.addSocket(hostAE, socket);
|
this.addSocket(hostAE, socket);
|
||||||
|
|
||||||
if (options.contexts) {
|
if (options.contexts) {
|
||||||
socket.setPresentationContexts(options.contexts);
|
socket.setPresentationContexts(options.contexts);
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
var Future = Npm.require('fibers/future');
|
var Future = Npm.require('fibers/future');
|
||||||
|
|
||||||
DIMSE = {};
|
DIMSE = {
|
||||||
|
connection: new Connection({
|
||||||
var conn = new Connection({
|
|
||||||
vr: {
|
vr: {
|
||||||
split: false
|
split: false
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
var conn = DIMSE.connection;
|
||||||
|
|
||||||
var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
|
var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
|
||||||
return {
|
return {
|
||||||
@ -64,35 +66,6 @@ var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
Meteor.startup(function() {
|
|
||||||
if (Meteor.settings.defaultServiceType !== 'dimse') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Meteor.settings.servers.dimse ||
|
|
||||||
!Meteor.settings.servers.dimse.length) {
|
|
||||||
console.error('dimse-config: ' + 'No DIMSE Servers provided.');
|
|
||||||
throw new Meteor.Error('dimse-config', 'No DIMSE Servers provided.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: [custom-servers] use active server and check if type is DIMSE
|
|
||||||
var peers = Meteor.settings.servers.dimse[0].peers;
|
|
||||||
if (!peers || !peers.length) {
|
|
||||||
console.error('dimse-config: ' + 'No DIMSE Peers provided.');
|
|
||||||
throw new Meteor.Error('dimse-config', 'No DIMSE Peers provided.');
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('Adding DIMSE peers');
|
|
||||||
try {
|
|
||||||
peers.forEach(function(peer) {
|
|
||||||
conn.addPeer(peer);
|
|
||||||
});
|
|
||||||
} catch(error) {
|
|
||||||
console.error('dimse-addPeers: ' + error);
|
|
||||||
throw new Meteor.Error('dimse-addPeers', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
DIMSE.associate = function(contexts, callback, options) {
|
DIMSE.associate = function(contexts, callback, options) {
|
||||||
var defaults = {
|
var defaults = {
|
||||||
contexts: contexts
|
contexts: contexts
|
||||||
@ -239,10 +212,10 @@ DIMSE.retrieveInstancesByStudyOnly = function(studyInstanceUID, params, options)
|
|||||||
0x0020000E: '',
|
0x0020000E: '',
|
||||||
0x00200011: ''
|
0x00200011: ''
|
||||||
};
|
};
|
||||||
var result = this.findSeries(Object.assign(defaultParams, params)),
|
var result = this.findSeries(Object.assign(defaultParams, params));
|
||||||
series = [],
|
var series = [];
|
||||||
conn = this,
|
var conn = this;
|
||||||
allInstances = [];
|
var allInstances = [];
|
||||||
|
|
||||||
result.on('result', function(msg) {
|
result.on('result', function(msg) {
|
||||||
series.push(msg);
|
series.push(msg);
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
import { Mongo } from 'meteor/mongo';
|
import { Mongo } from 'meteor/mongo';
|
||||||
|
|
||||||
// Servers describe the DICOM servers configurations
|
|
||||||
Servers = new Mongo.Collection('servers');
|
|
||||||
|
|
||||||
Timepoints = new Mongo.Collection('timepoints');
|
Timepoints = new Mongo.Collection('timepoints');
|
||||||
Studies = new Mongo.Collection('studies');
|
Studies = new Mongo.Collection('studies');
|
||||||
Measurements = new Mongo.Collection('measurements');
|
Measurements = new Mongo.Collection('measurements');
|
||||||
|
|||||||
@ -1,2 +1 @@
|
|||||||
Meteor.subscribe('reviewers');
|
Meteor.subscribe('reviewers');
|
||||||
Meteor.subscribe('servers');
|
|
||||||
|
|||||||
@ -1,30 +0,0 @@
|
|||||||
Template.serverInformationList.onCreated(() => {
|
|
||||||
const instance = Template.instance();
|
|
||||||
|
|
||||||
instance.api = {
|
|
||||||
add: () => instance.data.mode.set('create'),
|
|
||||||
edit(server) {
|
|
||||||
instance.data.currentItem.set(server);
|
|
||||||
instance.data.mode.set('edit');
|
|
||||||
},
|
|
||||||
delete(server) {
|
|
||||||
Meteor.call('serverRemove', server._id, error => {
|
|
||||||
// TODO: check for errors: not-authorized, data-write
|
|
||||||
});
|
|
||||||
},
|
|
||||||
use(server) {
|
|
||||||
Meteor.call('serverSetActive', server._id, error => {
|
|
||||||
// TODO: [custom-servers] check for errors: not-authorized, data-write
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.serverInformationList.helpers({
|
|
||||||
isActive: function(server) {
|
|
||||||
return server._id === Meteor.user().profile.activeServer;
|
|
||||||
},
|
|
||||||
servers: function() {
|
|
||||||
return Servers.find().fetch();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -203,7 +203,6 @@ Package.onUse(function(api) {
|
|||||||
|
|
||||||
// Server functions
|
// Server functions
|
||||||
api.addFiles('server/publications.js', 'server');
|
api.addFiles('server/publications.js', 'server');
|
||||||
api.addFiles('server/servers.js', 'server');
|
|
||||||
api.addFiles('server/methods.js', [ 'server' ]);
|
api.addFiles('server/methods.js', [ 'server' ]);
|
||||||
api.addFiles('server/reviewers.js', [ 'server' ]);
|
api.addFiles('server/reviewers.js', [ 'server' ]);
|
||||||
api.addFiles('server/createDemoUser.js', [ 'server' ]);
|
api.addFiles('server/createDemoUser.js', [ 'server' ]);
|
||||||
@ -242,23 +241,6 @@ Package.onUse(function(api) {
|
|||||||
api.addFiles('lib/handleMeasurementModified.js', 'client');
|
api.addFiles('lib/handleMeasurementModified.js', 'client');
|
||||||
api.addFiles('lib/handleMeasurementRemoved.js', 'client');
|
api.addFiles('lib/handleMeasurementRemoved.js', 'client');
|
||||||
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html', 'client');
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.js', 'client');
|
|
||||||
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationDimse/serverInformationDimse.html', 'client');
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationDimse/serverInformationDimse.js', 'client');
|
|
||||||
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationForm/serverInformationForm.html', 'client');
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationForm/serverInformationForm.js', 'client');
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationForm/serverInformationFormField.html', 'client');
|
|
||||||
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationList/serverInformationList.html', 'client');
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationList/serverInformationList.js', 'client');
|
|
||||||
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationModal/serverInformationModal.html', 'client');
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationModal/serverInformationModal.styl', 'client');
|
|
||||||
api.addFiles('client/components/serverInformation/serverInformationModal/serverInformationModal.js', 'client');
|
|
||||||
|
|
||||||
// API classes
|
// API classes
|
||||||
api.addFiles('client/api/timepoint.js');
|
api.addFiles('client/api/timepoint.js');
|
||||||
api.addFiles('client/api/measurement.js');
|
api.addFiles('client/api/measurement.js');
|
||||||
@ -299,7 +281,6 @@ Package.onUse(function(api) {
|
|||||||
api.export('TrialCriteriaTypes', 'client');
|
api.export('TrialCriteriaTypes', 'client');
|
||||||
|
|
||||||
// Export collections spanning both client and server
|
// Export collections spanning both client and server
|
||||||
api.export('Servers', [ 'client', 'server' ]);
|
|
||||||
api.export('AdditionalFindings', [ 'client', 'server' ]);
|
api.export('AdditionalFindings', [ 'client', 'server' ]);
|
||||||
api.export('ImageMeasurements', [ 'client', 'server' ]);
|
api.export('ImageMeasurements', [ 'client', 'server' ]);
|
||||||
api.export('Measurements', [ 'client', 'server' ]);
|
api.export('Measurements', [ 'client', 'server' ]);
|
||||||
|
|||||||
@ -46,10 +46,6 @@ Meteor.publish('reviewers', function() {
|
|||||||
return Reviewers.find();
|
return Reviewers.find();
|
||||||
});
|
});
|
||||||
|
|
||||||
Meteor.publish('servers', () => {
|
|
||||||
return Servers.find();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Temporary fix to drop all Collections on server restart
|
// Temporary fix to drop all Collections on server restart
|
||||||
// http://stackoverflow.com/questions/23891631/meteor-how-can-i-drop-all-mongo-collections-and-clear-all-data-on-startup
|
// http://stackoverflow.com/questions/23891631/meteor-how-can-i-drop-all-mongo-collections-and-clear-all-data-on-startup
|
||||||
Meteor.startup(function() {
|
Meteor.startup(function() {
|
||||||
|
|||||||
@ -126,7 +126,7 @@ OHIF.mixins.schemaData = new OHIF.Mixin({
|
|||||||
|
|
||||||
// Stop here if there's no schema data for current key
|
// Stop here if there's no schema data for current key
|
||||||
if (!currentSchema) {
|
if (!currentSchema) {
|
||||||
return;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the schema is a Number
|
// Check if the schema is a Number
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
<template name="cineDialog">
|
<template name="cineDialog">
|
||||||
{{#form id='cineDialog' class='noselect' schema=instance.schema api=instance.api}}
|
{{#form id='cineDialog' class='noselect' schema=instance.schema api=instance.api}}
|
||||||
{{>inputHidden key='intervalId'}}
|
{{>inputHidden key='intervalId'}}
|
||||||
<h5>CINE Controls</h5>
|
|
||||||
<div class="cine-navigation">
|
<div class="cine-navigation">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
{{#button disabled=(displaySetDisabled false) action='displaySetPrevious' title='Previous display set'}}
|
{{#button disabled=(displaySetDisabled false) action='displaySetPrevious' title='Previous display set'}}
|
||||||
@ -20,9 +19,6 @@
|
|||||||
{{#button action='cinePrevious' title='Previous image'}}
|
{{#button action='cinePrevious' title='Previous image'}}
|
||||||
<i class="fa fa-step-backward"></i>
|
<i class="fa fa-step-backward"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
{{#button action='cineSlowDown' title='Slow playback'}}
|
|
||||||
<i class="fa fa-backward"></i>
|
|
||||||
{{/button}}
|
|
||||||
{{#button action='cineToggle' title='Play / Stop' class=(valueIf isPlaying 'active' '')}}
|
{{#button action='cineToggle' title='Play / Stop' class=(valueIf isPlaying 'active' '')}}
|
||||||
{{#if isPlaying}}
|
{{#if isPlaying}}
|
||||||
<i class="fa fa-fw fa-stop"></i>
|
<i class="fa fa-fw fa-stop"></i>
|
||||||
@ -30,9 +26,6 @@
|
|||||||
<i class="fa fa-fw fa-play"></i>
|
<i class="fa fa-fw fa-play"></i>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/button}}
|
{{/button}}
|
||||||
{{#button action='cineSpeedUp' title='Increase playback speed'}}
|
|
||||||
<i class="fa fa-forward"></i>
|
|
||||||
{{/button}}
|
|
||||||
{{#button action='cineNext' title='Next image'}}
|
{{#button action='cineNext' title='Next image'}}
|
||||||
<i class="fa fa-step-forward"></i>
|
<i class="fa fa-step-forward"></i>
|
||||||
{{/button}}
|
{{/button}}
|
||||||
@ -42,14 +35,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cine-options">
|
<div class="cine-options">
|
||||||
{{>inputCheckbox key='loop' labelClass='pull-right m-a-0'}}
|
|
||||||
<div class="fps-section">
|
<div class="fps-section">
|
||||||
{{#inputRange key='framesPerSecond' class='p-a-0' labelClass='form-group m-a-0' labelAsDiv=true}}
|
{{#inputRange key='framesPerSecond' class='p-a-0' labelClass='form-group m-a-0' labelAsDiv=true}}
|
||||||
{{#section 'labelAfterText'}}:
|
|
||||||
<span id="fps">{{framerate}}</span>
|
|
||||||
{{/section}}
|
|
||||||
{{/inputRange}}
|
{{/inputRange}}
|
||||||
</div>
|
</div>
|
||||||
|
<span id="fps">{{framerate}} fps</span>
|
||||||
</div>
|
</div>
|
||||||
{{/form}}
|
{{/form}}
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -21,7 +21,7 @@ Template.cineDialog.onCreated(() => {
|
|||||||
},
|
},
|
||||||
framesPerSecond: {
|
framesPerSecond: {
|
||||||
type: Number,
|
type: Number,
|
||||||
label: 'Cine Speed',
|
label: '',
|
||||||
defaultValue: 24,
|
defaultValue: 24,
|
||||||
min: 1,
|
min: 1,
|
||||||
max: 90,
|
max: 90,
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
@import "{design}/app.styl"
|
@import "{design}/app.styl"
|
||||||
|
|
||||||
#cineDialog
|
#cineDialog
|
||||||
theme('border', '1px solid $uiBorderColor', 0.95)
|
theme('border', '2px solid $uiBorderColor', 0.95)
|
||||||
theme('background', '$uiGrayDarkest', 0.95)
|
theme('background', '$uiGrayDarkest', 0.95)
|
||||||
theme('color', '$textSecondaryColor')
|
theme('color', '$textSecondaryColor')
|
||||||
border-radius: 8px
|
border-radius: 8px
|
||||||
bottom: 3px
|
bottom: 3px
|
||||||
box-sizing: border-box
|
box-sizing: border-box
|
||||||
height: 150px
|
height: 80px
|
||||||
left: 50%
|
left: 50%
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
padding: 10px
|
padding: 10px
|
||||||
position: absolute
|
position: absolute
|
||||||
right: 3px
|
right: 3px
|
||||||
top: 50%
|
top: 2%
|
||||||
width: 300px
|
width: 300px
|
||||||
z-index: 1000
|
z-index: 1000
|
||||||
transform(translateX(-50%) translateY(-50%))
|
transform(translateX(-50%) translateY(-50%))
|
||||||
@ -36,9 +36,10 @@
|
|||||||
&:active, &.active
|
&:active, &.active
|
||||||
theme('color', '$activeColor')
|
theme('color', '$activeColor')
|
||||||
|
|
||||||
|
|
||||||
.cine-navigation
|
.cine-navigation
|
||||||
position: absolute
|
position: absolute
|
||||||
right: 24px
|
right: 4px
|
||||||
top: 4px
|
top: 4px
|
||||||
|
|
||||||
.btn
|
.btn
|
||||||
@ -49,12 +50,19 @@
|
|||||||
line-height: 36px
|
line-height: 36px
|
||||||
|
|
||||||
.cine-controls
|
.cine-controls
|
||||||
display: table
|
left: 0px
|
||||||
margin: 0 auto
|
|
||||||
|
|
||||||
.cine-options
|
.cine-options
|
||||||
padding: 5px 0
|
padding: 0px 0
|
||||||
overflow: auto
|
|
||||||
|
.fps-section
|
||||||
|
width: 175px
|
||||||
|
float: left
|
||||||
|
|
||||||
|
#fps
|
||||||
|
float: right
|
||||||
|
padding: 5px 10px 0 0
|
||||||
|
|
||||||
.loop-section
|
.loop-section
|
||||||
padding-right: 12px
|
padding-right: 12px
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,9 @@
|
|||||||
import { Mongo } from 'meteor/mongo';
|
import { Mongo } from 'meteor/mongo';
|
||||||
|
|
||||||
StudyImportStatus = new Mongo.Collection('studyImportStatus');
|
StudyImportStatus = new Mongo.Collection('studyImportStatus');
|
||||||
|
|
||||||
|
// Servers describe the DICOM servers configurations
|
||||||
|
Servers = new Mongo.Collection('servers');
|
||||||
|
|
||||||
|
// CurrentServer is a single document collection to describe which of the Servers is being used
|
||||||
|
CurrentServer = new Mongo.Collection('currentServer');
|
||||||
|
|||||||
14
Packages/worklist/both/lib/getCurrentServer.js
Normal file
14
Packages/worklist/both/lib/getCurrentServer.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Retrieves the current server configuration used to retrieve studies
|
||||||
|
*/
|
||||||
|
getCurrentServer = () => {
|
||||||
|
const currentServer = CurrentServer.findOne();
|
||||||
|
|
||||||
|
if (!currentServer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const serverConfiguration = Servers.findOne({ _id: currentServer.serverId });
|
||||||
|
|
||||||
|
return serverConfiguration;
|
||||||
|
};
|
||||||
@ -14,6 +14,12 @@ const serverTypeDefinitions = {
|
|||||||
optional: true
|
optional: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const wadoUriRootDefinitions = {
|
||||||
|
type: String,
|
||||||
|
label: 'WADO URI root',
|
||||||
|
max: 1000
|
||||||
|
};
|
||||||
|
|
||||||
export const DICOMWebRequestOptions = new SimpleSchema({
|
export const DICOMWebRequestOptions = new SimpleSchema({
|
||||||
auth: {
|
auth: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -40,11 +46,7 @@ export const DICOMWebRequestOptions = new SimpleSchema({
|
|||||||
export const DICOMWebServer = new SimpleSchema({
|
export const DICOMWebServer = new SimpleSchema({
|
||||||
name: serverNameDefinitions,
|
name: serverNameDefinitions,
|
||||||
type: serverTypeDefinitions,
|
type: serverTypeDefinitions,
|
||||||
wadoUriRoot: {
|
wadoUriRoot: wadoUriRootDefinitions,
|
||||||
type: String,
|
|
||||||
label: 'WADO URI root',
|
|
||||||
max: 1000
|
|
||||||
},
|
|
||||||
wadoRoot: {
|
wadoRoot: {
|
||||||
type: String,
|
type: String,
|
||||||
label: 'WADO root',
|
label: 'WADO root',
|
||||||
@ -106,7 +108,7 @@ export const DIMSEPeer = new SimpleSchema({
|
|||||||
},
|
},
|
||||||
supportsInstanceRetrievalByStudyUid: {
|
supportsInstanceRetrievalByStudyUid: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
label: 'Supports instance retrieval by StudyUid?',
|
label: 'Supports instance retrieval by StudyUid',
|
||||||
defaultValue: true
|
defaultValue: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -114,6 +116,7 @@ export const DIMSEPeer = new SimpleSchema({
|
|||||||
export const DIMSEServer = new SimpleSchema({
|
export const DIMSEServer = new SimpleSchema({
|
||||||
name: serverNameDefinitions,
|
name: serverNameDefinitions,
|
||||||
type: serverTypeDefinitions,
|
type: serverTypeDefinitions,
|
||||||
|
wadoUriRoot: wadoUriRootDefinitions,
|
||||||
peers: {
|
peers: {
|
||||||
type: [DIMSEPeer],
|
type: [DIMSEPeer],
|
||||||
label: 'Peer List',
|
label: 'Peer List',
|
||||||
@ -141,6 +144,11 @@ export const UISettings = new SimpleSchema({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
label: 'The UP/DOWN display set navigation buttons will iterate over all the viewports at once?',
|
label: 'The UP/DOWN display set navigation buttons will iterate over all the viewports at once?',
|
||||||
defaultValue: false
|
defaultValue: false
|
||||||
|
},
|
||||||
|
showCineDialogOnRendered: {
|
||||||
|
type: Boolean,
|
||||||
|
label: 'The Cine dialog will be displayed by default',
|
||||||
|
defaultValue: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
2
Packages/worklist/client/collections/subscriptions.js
Normal file
2
Packages/worklist/client/collections/subscriptions.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Meteor.subscribe('servers');
|
||||||
|
Meteor.subscribe('currentServer');
|
||||||
@ -1,8 +1,15 @@
|
|||||||
<template name="serverInformationDimse">
|
<template name="serverInformationDimse">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
{{>inputText labelClass='form-group' key='wadoUriRoot'}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel panel-default panel-body">
|
<div class="panel panel-default panel-body">
|
||||||
<div class="clearfix">
|
<div class="clearfix">
|
||||||
<h4 class="pull-left">Peer List</h4>
|
<h4 class="pull-left">Peer List</h4>
|
||||||
<button class="btn btn-primary pull-right js-new-peer">New peer</button>
|
{{#button class='btn btn-primary pull-right'
|
||||||
|
action='newPeer' params=peer
|
||||||
|
}}New peer{{/button}}
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
{{#group class='row' key='peers' arrayValues=true}}
|
{{#group class='row' key='peers' arrayValues=true}}
|
||||||
@ -25,17 +32,25 @@
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<strong>Settings</strong>
|
<strong>Settings</strong>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="form-control clearfix">
|
<div class="form-control height-auto clearfix">
|
||||||
<div class="checkbox pull-left">
|
<div class="checkbox pull-left">
|
||||||
{{>inputCheckbox key='default'}}
|
{{>inputCheckbox key='default'}}
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox pull-left">
|
<div class="checkbox pull-left">
|
||||||
{{>inputCheckbox key='server'}}
|
{{>inputCheckbox key='server'}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="checkbox pull-left">
|
||||||
|
{{>inputCheckbox key='supportsInstanceRetrievalByStudyUid'}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-lg-12 text-right">
|
||||||
|
{{#button class='btn btn-sm btn-danger'
|
||||||
|
action='removePeer' params=@index
|
||||||
|
}}Remove{{/button}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/group}}
|
{{/group}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
@ -7,6 +7,23 @@ Template.serverInformationDimse.onCreated(() => {
|
|||||||
instance.peers.set(currentItem.peers || []);
|
instance.peers.set(currentItem.peers || []);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const api = instance.data.api;
|
||||||
|
_.extend(api, {
|
||||||
|
newPeer() {
|
||||||
|
const peers = instance.peers.get();
|
||||||
|
peers.push({});
|
||||||
|
instance.peers.set(peers);
|
||||||
|
},
|
||||||
|
removePeer(peerIndex) {
|
||||||
|
const peers = instance.peers.get();
|
||||||
|
peers.splice(peerIndex, 1);
|
||||||
|
instance.peers.set(peers);
|
||||||
|
|
||||||
|
const data = instance.data.currentItem.get();
|
||||||
|
data.peers = peers;
|
||||||
|
Tracker.afterFlush(() => instance.data.form.value(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.serverInformationDimse.onRendered(() => {
|
Template.serverInformationDimse.onRendered(() => {
|
||||||
@ -19,12 +36,3 @@ Template.serverInformationDimse.onRendered(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.serverInformationDimse.events({
|
|
||||||
'click .js-new-peer'(event, instance) {
|
|
||||||
event.preventDefault();
|
|
||||||
const peers = instance.peers.get();
|
|
||||||
peers.push({});
|
|
||||||
instance.peers.set(peers);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template name="serverInformationForm">
|
<template name="serverInformationForm">
|
||||||
{{#form class='server-information-form' schema=instance.currentSchema api=instance.api}}
|
{{#form class='server-information-form' schema=instance.currentSchema api=this.api}}
|
||||||
{{>inputHidden key='_id'}}
|
{{>inputHidden key='_id'}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
@ -1,13 +1,13 @@
|
|||||||
import { Template } from 'meteor/templating';
|
import { Template } from 'meteor/templating';
|
||||||
import { ReactiveVar } from 'meteor/reactive-var';
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
import { Tracker } from 'meteor/tracker';
|
import { Tracker } from 'meteor/tracker';
|
||||||
import { DICOMWebServer as dicomSchema } from 'meteor/worklist/both/schema';
|
import { DICOMWebServer as dicomSchema } from 'meteor/worklist/both/schema.js';
|
||||||
import { DIMSEServer as dimseSchema } from 'meteor/worklist/both/schema';
|
import { DIMSEServer as dimseSchema } from 'meteor/worklist/both/schema.js';
|
||||||
|
|
||||||
Template.serverInformationForm.onCreated(() => {
|
Template.serverInformationForm.onCreated(() => {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
|
|
||||||
instance.api = {
|
instance.data.api = {
|
||||||
save() {
|
save() {
|
||||||
// Stop here if the form validation fails
|
// Stop here if the form validation fails
|
||||||
if (!instance.data.form.validate()) {
|
if (!instance.data.form.validate()) {
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
Template.serverInformationList.onCreated(() => {
|
||||||
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
instance.api = {
|
||||||
|
add: () => instance.data.mode.set('create'),
|
||||||
|
edit(server) {
|
||||||
|
instance.data.currentItem.set(server);
|
||||||
|
instance.data.mode.set('edit');
|
||||||
|
},
|
||||||
|
delete(server) {
|
||||||
|
// TODO: Replace this for confirmation dialog after LT-refactor is merged back to master
|
||||||
|
if (!confirm('Are you sure you want to remove this peer?')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.call('serverRemove', server._id, error => {
|
||||||
|
// TODO: check for errors: data-write
|
||||||
|
});
|
||||||
|
},
|
||||||
|
use(server) {
|
||||||
|
Meteor.call('serverSetActive', server._id, error => {
|
||||||
|
// TODO: check for errors: data-write
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.serverInformationList.helpers({
|
||||||
|
isActive: function(server) {
|
||||||
|
const currentServer = CurrentServer.findOne();
|
||||||
|
if (!currentServer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return server._id === currentServer.serverId;
|
||||||
|
},
|
||||||
|
servers: function() {
|
||||||
|
const options = {
|
||||||
|
sort: {
|
||||||
|
origin: -1,
|
||||||
|
type: 1,
|
||||||
|
name: 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return Servers.find({}, options).fetch();
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -34,6 +34,11 @@ switchToTab = function(contentId) {
|
|||||||
var container;
|
var container;
|
||||||
if (contentId === 'worklistTab') {
|
if (contentId === 'worklistTab') {
|
||||||
container = $('.tab-content').find('#worklistTab').get(0);
|
container = $('.tab-content').find('#worklistTab').get(0);
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var worklistContainer = document.createElement('div');
|
var worklistContainer = document.createElement('div');
|
||||||
worklistContainer.classList.add('worklistContainer');
|
worklistContainer.classList.add('worklistContainer');
|
||||||
container.appendChild(worklistContainer);
|
container.appendChild(worklistContainer);
|
||||||
|
|||||||
@ -1,3 +1,6 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { Tracker } from 'meteor/tracker';
|
||||||
|
|
||||||
Worklist = {
|
Worklist = {
|
||||||
functions: {},
|
functions: {},
|
||||||
callbacks: {}
|
callbacks: {}
|
||||||
@ -11,3 +14,18 @@ function dblClickOnStudy(data) {
|
|||||||
var title = formatPN(data.patientName);
|
var title = formatPN(data.patientName);
|
||||||
openNewTab(data.studyInstanceUid, title);
|
openNewTab(data.studyInstanceUid, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let currentServerChangeHandlerFirstRun = true;
|
||||||
|
const currentServerChangeHandler = () => {
|
||||||
|
if (currentServerChangeHandlerFirstRun) {
|
||||||
|
currentServerChangeHandlerFirstRun = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switchToTab('worklistTab');
|
||||||
|
};
|
||||||
|
|
||||||
|
CurrentServer.find().observe({
|
||||||
|
added: currentServerChangeHandler,
|
||||||
|
changed: currentServerChangeHandler
|
||||||
|
});
|
||||||
|
|||||||
@ -16,6 +16,7 @@ Package.onUse(function (api) {
|
|||||||
api.use('rwatts:uuid');
|
api.use('rwatts:uuid');
|
||||||
api.use('silentcicero:jszip');
|
api.use('silentcicero:jszip');
|
||||||
api.use('aldeed:simple-schema');
|
api.use('aldeed:simple-schema');
|
||||||
|
api.use('accounts-base');
|
||||||
|
|
||||||
// Note: MomentJS appears to be required for Bootstrap3 Datepicker, but not a dependency for some reason
|
// Note: MomentJS appears to be required for Bootstrap3 Datepicker, but not a dependency for some reason
|
||||||
api.use('momentjs:moment');
|
api.use('momentjs:moment');
|
||||||
@ -39,8 +40,12 @@ Package.onUse(function (api) {
|
|||||||
// console for debugging purposes
|
// console for debugging purposes
|
||||||
api.addFiles('log.js');
|
api.addFiles('log.js');
|
||||||
|
|
||||||
api.addFiles('both/collections.js', [ 'client', 'server' ]);
|
api.addFiles('both/collections.js', ['client', 'server']);
|
||||||
api.addFiles('both/schema.js', [ 'client', 'server' ]);
|
api.addFiles('both/schema.js', ['client', 'server']);
|
||||||
|
api.addFiles('both/lib/getCurrentServer.js', ['client', 'server']);
|
||||||
|
|
||||||
|
// Client collections and subscriptions
|
||||||
|
api.addFiles('client/collections/subscriptions.js', 'client');
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
api.addFiles('client/components/worklist.html', 'client');
|
api.addFiles('client/components/worklist.html', 'client');
|
||||||
@ -81,6 +86,23 @@ Package.onUse(function (api) {
|
|||||||
api.addFiles('client/components/seriesDetailsTable/seriesDetailsTable.styl', 'client');
|
api.addFiles('client/components/seriesDetailsTable/seriesDetailsTable.styl', 'client');
|
||||||
api.addFiles('client/components/seriesDetailsTable/seriesDetailsTable.js', 'client');
|
api.addFiles('client/components/seriesDetailsTable/seriesDetailsTable.js', 'client');
|
||||||
|
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.html', 'client');
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationDicomWeb/serverInformationDicomWeb.js', 'client');
|
||||||
|
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationDimse/serverInformationDimse.html', 'client');
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationDimse/serverInformationDimse.js', 'client');
|
||||||
|
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationForm/serverInformationForm.html', 'client');
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationForm/serverInformationForm.js', 'client');
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationForm/serverInformationFormField.html', 'client');
|
||||||
|
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationList/serverInformationList.html', 'client');
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationList/serverInformationList.js', 'client');
|
||||||
|
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationModal/serverInformationModal.html', 'client');
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationModal/serverInformationModal.styl', 'client');
|
||||||
|
api.addFiles('client/components/serverInformation/serverInformationModal/serverInformationModal.js', 'client');
|
||||||
|
|
||||||
// Client-side library functions
|
// Client-side library functions
|
||||||
api.addFiles('client/lib/getStudyMetadata.js', 'client');
|
api.addFiles('client/lib/getStudyMetadata.js', 'client');
|
||||||
api.addFiles('client/lib/getStudiesMetadata.js', 'client');
|
api.addFiles('client/lib/getStudiesMetadata.js', 'client');
|
||||||
@ -95,6 +117,7 @@ Package.onUse(function (api) {
|
|||||||
// Server-side functions
|
// Server-side functions
|
||||||
api.addFiles('server/publications.js', 'server');
|
api.addFiles('server/publications.js', 'server');
|
||||||
api.addFiles('server/validateServerConfiguration.js', 'server');
|
api.addFiles('server/validateServerConfiguration.js', 'server');
|
||||||
|
api.addFiles('server/servers.js', 'server');
|
||||||
api.addFiles('server/lib/remoteGetValue.js', 'server');
|
api.addFiles('server/lib/remoteGetValue.js', 'server');
|
||||||
api.addFiles('server/lib/encodeQueryData.js', 'server');
|
api.addFiles('server/lib/encodeQueryData.js', 'server');
|
||||||
|
|
||||||
@ -113,12 +136,20 @@ Package.onUse(function (api) {
|
|||||||
api.addFiles('server/services/dimse/instances.js', 'server');
|
api.addFiles('server/services/dimse/instances.js', 'server');
|
||||||
api.addFiles('server/services/dimse/studies.js', 'server');
|
api.addFiles('server/services/dimse/studies.js', 'server');
|
||||||
api.addFiles('server/services/dimse/retrieveMetadata.js', 'server');
|
api.addFiles('server/services/dimse/retrieveMetadata.js', 'server');
|
||||||
|
api.addFiles('server/services/dimse/setup.js', 'server');
|
||||||
|
|
||||||
// Study, instance, and metadata retrieval from remote PACS via Orthanc as a proxy
|
// Study, instance, and metadata retrieval from remote PACS via Orthanc as a proxy
|
||||||
api.addFiles('server/services/remote/instances.js', 'server');
|
api.addFiles('server/services/remote/instances.js', 'server');
|
||||||
api.addFiles('server/services/remote/studies.js', 'server');
|
api.addFiles('server/services/remote/studies.js', 'server');
|
||||||
api.addFiles('server/services/remote/retrieveMetadata.js', 'server');
|
api.addFiles('server/services/remote/retrieveMetadata.js', 'server');
|
||||||
|
|
||||||
|
// Export Servers and CurrentServer Collections
|
||||||
|
api.export('Servers', ['client', 'server']);
|
||||||
|
api.export('CurrentServer', ['client', 'server']);
|
||||||
|
|
||||||
|
// Export shared lib functions
|
||||||
|
api.export('getCurrentServer', ['client', 'server']);
|
||||||
|
|
||||||
api.export('Services', 'server');
|
api.export('Services', 'server');
|
||||||
|
|
||||||
// Export Worklist helper functions for usage in Routes
|
// Export Worklist helper functions for usage in Routes
|
||||||
|
|||||||
@ -6,16 +6,17 @@ Meteor.methods({
|
|||||||
GetStudyMetadata: function(studyInstanceUid) {
|
GetStudyMetadata: function(studyInstanceUid) {
|
||||||
log.info('GetStudyMetadata(%s)', studyInstanceUid);
|
log.info('GetStudyMetadata(%s)', studyInstanceUid);
|
||||||
|
|
||||||
if (!Meteor.settings.servers.dicomWeb) {
|
// Get the server data. This is user-defined in the config.json files or through servers
|
||||||
throw 'No properly configured server was available over DICOMWeb';
|
// configuration modal
|
||||||
|
const server = getCurrentServer();
|
||||||
|
|
||||||
|
if (!server) {
|
||||||
|
throw 'No properly configured server was available over DICOMWeb or DIMSE.';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Meteor.settings.servers.dicomWeb && Meteor.settings.defaultServiceType === 'dicomWeb') {
|
if (server.type === 'dicomWeb') {
|
||||||
// Get the server data. This is user-defined in the
|
|
||||||
// config.json files used to run the Meteor server
|
|
||||||
var server = Meteor.settings.servers.dicomWeb[0];
|
|
||||||
return Services.WADO.RetrieveMetadata(server, studyInstanceUid);
|
return Services.WADO.RetrieveMetadata(server, studyInstanceUid);
|
||||||
} else if (Meteor.settings.servers.dimse && Meteor.settings.defaultServiceType === 'dimse') {
|
} else if (server.type === 'dimse') {
|
||||||
return Services.DIMSE.RetrieveMetadata(studyInstanceUid);
|
return Services.DIMSE.RetrieveMetadata(studyInstanceUid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,7 +39,8 @@ Meteor.methods({
|
|||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
importSupported: function() {
|
importSupported: function() {
|
||||||
if (Meteor.settings.servers.dimse && Meteor.settings.defaultServiceType === 'dimse') {
|
const server = getCurrentServer();
|
||||||
|
if (server && server.type === 'dimse') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -53,13 +54,17 @@ Meteor.methods({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Meteor.settings.servers.dicomWeb && Meteor.settings.defaultServiceType === 'dicomWeb') {
|
const server = getCurrentServer();
|
||||||
|
|
||||||
|
if (!server) {
|
||||||
|
throw 'No properly configured server was available over DICOMWeb or DIMSE.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server.type === 'dicomWeb') {
|
||||||
//TODO: Support importing studies into dicomWeb
|
//TODO: Support importing studies into dicomWeb
|
||||||
console.log('Importing studies into dicomWeb is currently not supported.');
|
console.log('Importing studies into dicomWeb is currently not supported.');
|
||||||
} else if (Meteor.settings.servers.dimse && Meteor.settings.defaultServiceType === 'dimse') {
|
} else if (server.type === 'dimse') {
|
||||||
importStudiesDIMSE(studiesToImport, studyImportStatusId);
|
importStudiesDIMSE(studiesToImport, studyImportStatusId);
|
||||||
} else {
|
|
||||||
throw 'No properly configured server was available over DICOMWeb or DIMSE.';
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,19 +1,22 @@
|
|||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
/**
|
/**
|
||||||
* Use the specified filter to conduct a search from the DICOM server
|
* Use the specified filter to conduct a search from the DICOM server
|
||||||
|
*
|
||||||
* @param filter
|
* @param filter
|
||||||
*/
|
*/
|
||||||
WorklistSearch: function(filter) {
|
WorklistSearch(filter) {
|
||||||
if (Meteor.settings.servers.dicomWeb && Meteor.settings.defaultServiceType === 'dicomWeb') {
|
// Get the server data. This is user-defined in the config.json files or through servers
|
||||||
// Get the server data. This is user-defined in the
|
// configuration modal
|
||||||
// config.json files used to run the Meteor server
|
const server = getCurrentServer();
|
||||||
var server = Meteor.settings.servers.dicomWeb[0];
|
|
||||||
|
|
||||||
return Services.QIDO.Studies(server, filter);
|
if (!server) {
|
||||||
} else if (Meteor.settings.servers.dimse && Meteor.settings.defaultServiceType === 'dimse') {
|
|
||||||
return Services.DIMSE.Studies(filter);
|
|
||||||
} else {
|
|
||||||
throw 'No properly configured server was available over DICOMWeb or DIMSE.';
|
throw 'No properly configured server was available over DICOMWeb or DIMSE.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server.type === 'dicomWeb') {
|
||||||
|
return Services.QIDO.Studies(server, filter);
|
||||||
|
} else if (server.type === 'dimse') {
|
||||||
|
return Services.DIMSE.Studies(filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,3 +1,11 @@
|
|||||||
Meteor.publish('studyImportStatus', () => {
|
Meteor.publish('studyImportStatus', () => {
|
||||||
return StudyImportStatus.find();
|
return StudyImportStatus.find();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Meteor.publish('servers', () => {
|
||||||
|
return Servers.find();
|
||||||
|
});
|
||||||
|
|
||||||
|
Meteor.publish('currentServer', () => {
|
||||||
|
return CurrentServer.find();
|
||||||
|
});
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { Accounts } from 'meteor/accounts-base';
|
|
||||||
|
|
||||||
Meteor.startup(function() {
|
Meteor.startup(function() {
|
||||||
|
Servers.remove({
|
||||||
|
origin: 'json'
|
||||||
|
});
|
||||||
|
|
||||||
_.each(Meteor.settings.servers, function(endpoints, serverType) {
|
_.each(Meteor.settings.servers, function(endpoints, serverType) {
|
||||||
_.each(endpoints, function(endpoint) {
|
_.each(endpoints, function(endpoint) {
|
||||||
var server = _.clone(endpoint);
|
var server = _.clone(endpoint);
|
||||||
@ -10,28 +13,46 @@ Meteor.startup(function() {
|
|||||||
Servers.insert(server);
|
Servers.insert(server);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ServersControl.resetCurrentServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
class ServersControl {
|
class ServersControl {
|
||||||
|
|
||||||
static validateUser() {
|
|
||||||
if (!Meteor.userId()) {
|
|
||||||
throw new Meteor.Error('not-authorized');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static writeCallback(error, affected) {
|
static writeCallback(error, affected) {
|
||||||
if (error) {
|
if (error) {
|
||||||
throw new Meteor.Error('data-write', error);
|
throw new Meteor.Error('data-write', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static resetCurrentServer() {
|
||||||
|
const currentServer = CurrentServer.findOne();
|
||||||
|
if (currentServer && Servers.find({ _id: currentServer.serverId }).count()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newServer = Servers.findOne({
|
||||||
|
origin: 'json',
|
||||||
|
type: Meteor.settings.defaultServiceType || 'dicomWeb'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (newServer) {
|
||||||
|
CurrentServer.remove({});
|
||||||
|
CurrentServer.insert({
|
||||||
|
serverId: newServer._id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static find(query) {
|
||||||
|
return Servers.find(query).fetch();
|
||||||
|
}
|
||||||
|
|
||||||
static save(serverSettings) {
|
static save(serverSettings) {
|
||||||
this.validateUser();
|
const query = {
|
||||||
var query = {
|
|
||||||
_id: serverSettings._id
|
_id: serverSettings._id
|
||||||
};
|
};
|
||||||
var options = {
|
const options = {
|
||||||
upsert: true
|
upsert: true
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -43,29 +64,28 @@ class ServersControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static setActive(serverId) {
|
static setActive(serverId) {
|
||||||
this.validateUser();
|
CurrentServer.remove({});
|
||||||
var query = {
|
CurrentServer.insert({
|
||||||
_id: Meteor.userId()
|
serverId: serverId
|
||||||
};
|
});
|
||||||
var data = {
|
|
||||||
$set: {
|
|
||||||
'profile.activeServer': serverId
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Accounts.users.update(query, data, this.writeCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static remove(serverId) {
|
static remove(serverId) {
|
||||||
this.validateUser();
|
|
||||||
var query = {
|
var query = {
|
||||||
_id: serverId
|
_id: serverId
|
||||||
};
|
};
|
||||||
return Servers.remove(query, this.writeCallback);
|
|
||||||
|
const removeStatus = Servers.remove(query, this.writeCallback);
|
||||||
|
|
||||||
|
ServersControl.resetCurrentServer();
|
||||||
|
|
||||||
|
return removeStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Meteor.methods({
|
Meteor.methods({
|
||||||
|
serverFind: query => ServersControl.find(query),
|
||||||
serverSave: serverSettings => ServersControl.save(serverSettings),
|
serverSave: serverSettings => ServersControl.save(serverSettings),
|
||||||
serverSetActive: serverId => ServersControl.setActive(serverId),
|
serverSetActive: serverId => ServersControl.setActive(serverId),
|
||||||
serverRemove: serverId => ServersControl.remove(serverId)
|
serverRemove: serverId => ServersControl.remove(serverId)
|
||||||
@ -31,12 +31,10 @@ function resultDataToStudyMetadata(resultData) {
|
|||||||
seriesList.push(series);
|
seriesList.push(series);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: [custom-servers] Check which peer it should point to
|
// TODO: Check which peer it should point to
|
||||||
var server = Meteor.settings.servers.dimse[0].peers[0];
|
var server = getCurrentServer().peers[0];
|
||||||
var host = Meteor.settings.servers.dimse.host,
|
|
||||||
port = Meteor.settings.servers.dimse.port;
|
|
||||||
|
|
||||||
var serverRoot = host + ':' + port;
|
var serverRoot = server.host + ':' + server.port;
|
||||||
|
|
||||||
var sopInstanceUid = instance[0x00080018];
|
var sopInstanceUid = instance[0x00080018];
|
||||||
var uri = serverRoot + '/studies/' + studyInstanceUid + '/series/' + seriesInstanceUid + '/instances/' + sopInstanceUid + '/frames/1';
|
var uri = serverRoot + '/studies/' + studyInstanceUid + '/series/' + seriesInstanceUid + '/instances/' + sopInstanceUid + '/frames/1';
|
||||||
|
|||||||
@ -110,8 +110,8 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Retrieve the actual data over WADO-URI
|
// Retrieve the actual data over WADO-URI
|
||||||
var server = Meteor.settings.servers.dicomWeb[0];
|
var server = getCurrentServer();
|
||||||
instanceSummary.wadouri = WADOProxy.convertURL(server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + "&contentType=application%2Fdicom", server.requestOptions);
|
instanceSummary.wadouri = WADOProxy.convertURL(server.wadoUriRoot + '?requestType=WADO&studyUID=' + studyInstanceUid + '&seriesUID=' + seriesInstanceUid + '&objectUID=' + sopInstanceUid + '&contentType=application%2Fdicom', server.requestOptions);
|
||||||
|
|
||||||
series.instances.push(instanceSummary);
|
series.instances.push(instanceSummary);
|
||||||
});
|
});
|
||||||
@ -127,8 +127,8 @@ function resultDataToStudyMetadata(studyInstanceUid, resultData) {
|
|||||||
* @returns {{seriesList: Array, patientName: *, patientId: *, accessionNumber: *, studyDate: *, modalities: *, studyDescription: *, imageCount: *, studyInstanceUid: *}}
|
* @returns {{seriesList: Array, patientName: *, patientId: *, accessionNumber: *, studyDate: *, modalities: *, studyDescription: *, imageCount: *, studyInstanceUid: *}}
|
||||||
*/
|
*/
|
||||||
Services.DIMSE.RetrieveMetadata = function(studyInstanceUid) {
|
Services.DIMSE.RetrieveMetadata = function(studyInstanceUid) {
|
||||||
// TODO: Find active server
|
// TODO: Check which peer it should point to
|
||||||
const activeServer = Meteor.settings.servers.dimse[0].peers[0];
|
const activeServer = getCurrentServer().peers[0];
|
||||||
const supportsInstanceRetrievalByStudyUid = activeServer.supportsInstanceRetrievalByStudyUid;
|
const supportsInstanceRetrievalByStudyUid = activeServer.supportsInstanceRetrievalByStudyUid;
|
||||||
let results;
|
let results;
|
||||||
|
|
||||||
|
|||||||
38
Packages/worklist/server/services/dimse/setup.js
Normal file
38
Packages/worklist/server/services/dimse/setup.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
|
||||||
|
const setupDIMSE = () => {
|
||||||
|
// Terminate existing DIMSE servers and sockets and clean up the connection object
|
||||||
|
DIMSE.connection.reset();
|
||||||
|
|
||||||
|
// Get the new server configuration
|
||||||
|
const server = getCurrentServer();
|
||||||
|
|
||||||
|
// Stop here if the new server is not of DIMSE type
|
||||||
|
if (server.type !== 'dimse') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if peers were defined in the server configuration and throw an error if not
|
||||||
|
const peers = server.peers;
|
||||||
|
if (!peers || !peers.length) {
|
||||||
|
console.error('dimse-config: ' + 'No DIMSE Peers provided.');
|
||||||
|
throw new Meteor.Error('dimse-config', 'No DIMSE Peers provided.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add all the DIMSE peers, establishing the connections
|
||||||
|
console.log('Adding DIMSE peers');
|
||||||
|
try {
|
||||||
|
peers.forEach(peer => DIMSE.connection.addPeer(peer));
|
||||||
|
} catch(error) {
|
||||||
|
console.error('dimse-addPeers: ' + error);
|
||||||
|
throw new Meteor.Error('dimse-addPeers', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Setup the DIMSE connections on startup or when the current server is changed
|
||||||
|
Meteor.startup(() => {
|
||||||
|
CurrentServer.find().observe({
|
||||||
|
added: setupDIMSE,
|
||||||
|
changed: setupDIMSE
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -17,6 +17,7 @@
|
|||||||
}],
|
}],
|
||||||
"dimse": [{
|
"dimse": [{
|
||||||
"name": "DCM4CHEE_DIMSE",
|
"name": "DCM4CHEE_DIMSE",
|
||||||
|
"wadoUriRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado",
|
||||||
"peers": [
|
"peers": [
|
||||||
{
|
{
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
],
|
],
|
||||||
"dimse": [{
|
"dimse": [{
|
||||||
"name": "OrthancDIMSE",
|
"name": "OrthancDIMSE",
|
||||||
|
"wadoUriRoot" : "http://52.87.58.190:8043/wado",
|
||||||
"peers": [
|
"peers": [
|
||||||
{
|
{
|
||||||
"host" : "localhost",
|
"host" : "localhost",
|
||||||
|
|||||||
@ -17,6 +17,7 @@
|
|||||||
],
|
],
|
||||||
"dimse" : [{
|
"dimse" : [{
|
||||||
"name": "ORTHANC_DIMSE",
|
"name": "ORTHANC_DIMSE",
|
||||||
|
"wadoUriRoot": "http://dicom-orthanc.medken.com/wado",
|
||||||
"peers": [
|
"peers": [
|
||||||
{
|
{
|
||||||
"host": "208.100.41.100",
|
"host": "208.100.41.100",
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
],
|
],
|
||||||
"dimse": [{
|
"dimse": [{
|
||||||
"name": "ORTHANC_DIMSE",
|
"name": "ORTHANC_DIMSE",
|
||||||
|
"wadoUriRoot": "http://localhost:8042/wado",
|
||||||
"peers": [
|
"peers": [
|
||||||
{
|
{
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user