Cleaned up some unused files (OHIF-54)

This commit is contained in:
Erik Ziegler 2016-08-10 15:39:31 +02:00
parent 4acf844eb1
commit f7e888d1be
98 changed files with 91 additions and 2215 deletions

View File

@ -1,2 +0,0 @@
PACKAGE_DIRS=..\Packages
meteor --settings ../config/localhostOrthanc.json

View File

@ -1,2 +0,0 @@
echo "Starting Meteor server..."
PACKAGE_DIRS="../Packages" meteor --settings ../config/localhostOrthanc.json

View File

@ -1,2 +0,0 @@
set PACKAGE_DIRS=..\Packages
meteor --settings ../config/medicalConnections.json

View File

@ -1 +0,0 @@
PACKAGE_DIRS="../Packages" meteor --settings ../config/medicalConnections.json

View File

@ -0,0 +1,2 @@
PACKAGE_DIRS=..\Packages
meteor --settings ../config/orthancDICOMWeb.json

View File

@ -0,0 +1,2 @@
echo "Starting Meteor server..."
PACKAGE_DIRS="../Packages" meteor --settings ../config/orthancDICOMWeb.json

View File

@ -1,2 +0,0 @@
set PACKAGE_DIRS=..\Packages
meteor --settings ../config/siimDCM4CHEE.json

View File

@ -1 +0,0 @@
PACKAGE_DIRS="../Packages" meteor --settings ../config/siimDCM4CHEE.json

View File

@ -1,13 +0,0 @@
docs:
mkdir -p docs
rm docs/* || true
# Make jsdoc3 documentation
jsdoc . -c conf.json -r -d docs -R README.md
# Make docco documentation (not sure if we will keep this)
mkdir -p docs/docco
docco {Packages,Viewer,LesionTracker}/{**/*,*} -o docs/docco -l parallel
# Force rebuild even if the docs exist
.PHONY: docs

View File

@ -1,2 +0,0 @@
set PACKAGE_DIRS=..\Packages
meteor --settings ../config/localhostOrthanc.json

View File

@ -1,2 +0,0 @@
echo "Starting Meteor server..."
PACKAGE_DIRS="../Packages" meteor --settings ../config/localhostOrthanc.json

View File

@ -1,2 +0,0 @@
set PACKAGE_DIRS=..\Packages
meteor --settings ../config/medicalConnections.json

View File

@ -1 +0,0 @@
PACKAGE_DIRS="../Packages" meteor --settings ../config/medicalConnections.json

View File

@ -0,0 +1,2 @@
set PACKAGE_DIRS=..\Packages
meteor --settings ../config/orthancDICOMWeb.json

View File

@ -0,0 +1,2 @@
echo "Starting Meteor server..."
PACKAGE_DIRS="../Packages" meteor --settings ../config/orthancDICOMWeb.json

View File

@ -1,2 +0,0 @@
set PACKAGE_DIRS=..\Packages
meteor --settings ../config/siimDCM4CHEE.json

View File

@ -1 +0,0 @@
PACKAGE_DIRS="../Packages" meteor --settings ../config/siimDCM4CHEE.json

View File

@ -1,43 +0,0 @@
// Pass in username, password as normal
// customLdapOptions should be passed in if you want to override LDAP_DEFAULTS
// on any particular call (if you have multiple ldap servers you'd like to connect to)
// You'll likely want to set the dn value here {dn: "..."}
Meteor.loginWithLDAP = function (user, password, customLdapOptions, callback) {
// Retrieve arguments as array
var args = [];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}
// Pull username and password
user = args.shift();
password = args.shift();
// Check if last argument is a function
// if it is, pop it off and set callback to it
if (typeof args[args.length - 1] == 'function') callback = args.pop(); else callback = null;
// if args still holds options item, grab it
if (args.length > 0) customLdapOptions = args.shift(); else customLdapOptions = {};
// Set up loginRequest object
var loginRequest = _.defaults({
username: user,
ldapPass: password
}, {
ldap: true,
ldapOptions: customLdapOptions
});
Accounts.callLoginMethod({
// Call login method with ldap = true
// This will hook into our login handler for ldap
methodArguments: [loginRequest],
userCallback: function (error, result) {
if (error) {
callback && callback(error);
} else {
callback && callback();
}
}
});
};

View File

@ -1,366 +0,0 @@
Future = Npm.require('fibers/future');
// At a minimum, set up LDAP_DEFAULTS.url and .dn according to
// your needs. url should appear as 'ldap://your.url.here'
// dn should appear in normal ldap format of comma separated attribute=value
// e.g. 'uid=someuser,cn=users,dc=somevalue'
LDAP_DEFAULTS = {
url: false,
port: '389',
dn: false,
searchDN: false,
searchCredentials: false,
createNewUser: true,
defaultDomain: false,
searchResultsProfileMap: false,
base: null,
search: '(objectclass=*)',
ldapsCertificate: false
};
/**
@class LDAP
@constructor
*/
var LDAP = function (options) {
// Set options
this.options = _.defaults(options, LDAP_DEFAULTS);
// Make sure options have been set
try {
check(this.options.url, String);
//check(this.options.dn, String);
} catch (e) {
throw new Meteor.Error('Bad Defaults', 'Options not set. Make sure to set LDAP_DEFAULTS.url and LDAP_DEFAULTS.dn!');
}
// Because NPM ldapjs module has some binary builds,
// We had to create a wraper package for it and build for
// certain architectures. The package typ:ldap-js exports
// 'MeteorWrapperLdapjs' which is a wrapper for the npm module
this.ldapjs = MeteorWrapperLdapjs;
};
/**
* Attempt to bind (authenticate) ldap
* and perform a dn search if specified
*
* @method ldapCheck
*
* @param {Object} options Object with username, ldapPass and overrides for LDAP_DEFAULTS object.
* Additionally the searchBeforeBind parameter can be specified, which is used to search for the DN
* if not provided.
*/
LDAP.prototype.ldapCheck = function (options) {
var self = this;
options = options || {};
if (options.hasOwnProperty('username') && options.hasOwnProperty('ldapPass')) {
var ldapAsyncFut = new Future();
// Create ldap client
var fullUrl = self.options.url + ':' + self.options.port;
var client = null;
if (self.options.url.indexOf('ldaps://') === 0) {
client = self.ldapjs.createClient({
url: fullUrl,
tlsOptions: {
ca: [self.options.ldapsCertificate]
}
});
}
else {
client = self.ldapjs.createClient({
url: fullUrl
});
}
// Slide @xyz.whatever from username if it was passed in
// and replace it with the domain specified in defaults
var emailSliceIndex = options.username.indexOf('@');
var username;
var domain = self.options.defaultDomain;
// If user appended email domain, strip it out
// And use the defaults.defaultDomain if set
if (emailSliceIndex !== -1) {
username = options.username.substring(0, emailSliceIndex);
domain = domain || options.username.substring((emailSliceIndex + 1), options.username.length);
} else {
username = options.username;
}
// If DN is provided, use it to bind
if (self.options.dn) {
// Attempt to bind to ldap server with provided info
client.bind(self.options.searchDN || self.options.dn, self.options.searchCredentials || options.ldapPass, function (err) {
try {
if (err) {
// Bind failure, return error
throw new Meteor.Error(err.code, err.message);
}
var handleSearchProfile = function (retObject, bindAfterSearch) {
retObject.emptySearch = true;
// construct list of ldap attributes to fetch
var attributes = [];
if (self.options.searchResultsProfileMap) {
self.options.searchResultsProfileMap.map(function (item) {
attributes.push(item.resultKey);
});
}
// use base if given, else the dn for the ldap search
var searchBase = self.options.base || self.options.dn;
var searchOptions = {
scope: 'sub',
sizeLimit: 1,
attributes: attributes,
filter: self.options.search
};
client.search(searchBase, searchOptions, function (err, res) {
if (err) {
ldapAsyncFut.return({
error: err
});
}
res.on('searchEntry', function (entry) {
retObject.emptySearch = false;
// Add entry results to return object
retObject.searchResults = entry.object;
if (bindAfterSearch) {
client.bind(retObject.searchResults.dn, options.ldapPass, function (err) {
try {
if (err) {
throw new Meteor.Error(err.code, err.message);
}
ldapAsyncFut.return(retObject);
} catch (e) {
ldapAsyncFut.return({
error: e
});
}
})
} else ldapAsyncFut.return(retObject);
});
// This call causes Future issue: "Future resolved more than once"
// Because it is already called in searchEntry handler
/*res.on('end', function () {
ldapAsyncFut.return(retObject);
});*/
});
};
var retObject = {
username: username,
searchResults: null,
email: domain ? username + '@' + domain : false
};
if (self.options.searchDN) {
handleSearchProfile(retObject, true);
} else if (self.options.searchResultsProfileMap) {
handleSearchProfile(retObject, false);
} else {
ldapAsyncFut.return(retObject);
}
} catch (e) {
ldapAsyncFut.return({
error: e
});
}
});
}
// DN not provided, search for DN and use result to bind
else if (typeof self.options.searchBeforeBind !== undefined) {
// initialize result
var retObject = {
username: username,
email: domain ? username + '@' + domain : false,
emptySearch: true,
searchResults: {}
};
// compile attribute list to return
var searchAttributes = ['dn'];
self.options.searchResultsProfileMap.map(function (item) {
searchAttributes.push(item.resultKey);
});
var filter = self.options.search;
Object.keys(options.ldapOptions.searchBeforeBind).forEach(function (searchKey) {
filter = '&' + filter + '(' + searchKey + '=' + options.ldapOptions.searchBeforeBind[searchKey] + ')';
});
var searchOptions = {
scope: 'sub',
sizeLimit: 1,
filter: filter
};
// perform LDAP search to determine DN
client.search(self.options.base, searchOptions, function (err, res) {
retObject.emptySearch = true;
res.on('searchEntry', function (entry) {
retObject.dn = entry.objectName;
retObject.username = retObject.dn;
retObject.emptySearch = false;
// Return search results if specified
if (self.options.searchResultsProfileMap) {
// construct list of ldap attributes to fetch
self.options.searchResultsProfileMap.map(function (item) {
retObject.searchResults[item.resultKey] = entry.object[item.resultKey];
});
}
// use the determined DN to bind
client.bind(entry.objectName, options.ldapPass, function (err) {
try {
if (err) {
throw new Meteor.Error(err.code, err.message);
}
else {
ldapAsyncFut.return(retObject);
}
}
catch (e) {
ldapAsyncFut.return({
error: e
});
}
});
});
// If no dn is found, return as is.
res.on('end', function (result) {
if (retObject.dn === undefined) {
ldapAsyncFut.return(retObject);
}
});
});
}
return ldapAsyncFut.wait();
} else {
throw new Meteor.Error(403, 'Missing LDAP Auth Parameter');
}
};
// Register login handler with Meteor
// Here we create a new LDAP instance with options passed from
// Meteor.loginWithLDAP on client side
// @param {Object} loginRequest will consist of username, ldapPass, ldap, and ldapOptions
Accounts.registerLoginHandler('ldap', function (loginRequest) {
// If 'ldap' isn't set in loginRequest object,
// then this isn't the proper handler (return undefined)
if (!loginRequest.ldap) {
return undefined;
}
// Instantiate LDAP with options
var userOptions = loginRequest.ldapOptions || {};
var ldapObj = new LDAP(userOptions);
// Call ldapCheck and get response
var ldapResponse = ldapObj.ldapCheck(loginRequest);
if (ldapResponse.error) {
return {
userId: null,
error: ldapResponse.error
};
}
else if (ldapResponse.emptySearch) {
return {
userId: null,
error: new Meteor.Error(403, 'User not found in LDAP')
};
}
else {
// Set initial userId and token vals
var userId = null;
var stampedToken = {
token: null
};
// Look to see if user already exists
var user = Meteor.users.findOne({
username: ldapResponse.username
});
// Login user if they exist
if (user) {
userId = user._id;
// Create hashed token so user stays logged in
stampedToken = Accounts._generateStampedLoginToken();
var hashStampedToken = Accounts._hashStampedToken(stampedToken);
// Update the user's token in mongo
Meteor.users.update(userId, {
$push: {
'services.resume.loginTokens': hashStampedToken
}
});
}
// Otherwise create user if option is set
else if (ldapObj.options.createNewUser) {
var userObject = {
username: ldapResponse.username
};
// Set email
if (ldapResponse.email) userObject.email = ldapResponse.email;
// Set profile values if specified in searchResultsProfileMap
if (ldapResponse.searchResults && ldapObj.options.searchResultsProfileMap.length > 0) {
var profileMap = ldapObj.options.searchResultsProfileMap;
var profileObject = {};
// Loop through profileMap and set values on profile object
for (var i = 0; i < profileMap.length; i++) {
var resultKey = profileMap[i].resultKey;
// If our search results have the specified property, set the profile property to its value
if (ldapResponse.searchResults.hasOwnProperty(resultKey)) {
profileObject[profileMap[i].profileProperty] = ldapResponse.searchResults[resultKey];
}
}
// Set userObject profile
userObject.profile = profileObject;
}
userId = Accounts.createUser(userObject);
} else {
// Ldap success, but no user created
console.log('LDAP Authentication succeeded for ' + ldapResponse.username + ', but no user exists in Meteor. Either create the user manually or set LDAP_DEFAULTS.createNewUser to true');
return {
userId: null,
error: new Meteor.Error(403, 'User found in LDAP but not in application')
};
}
return {
userId: userId,
token: stampedToken.token
};
}
});

View File

@ -1,28 +0,0 @@
Package.describe({
name: 'typ:accounts-ldap',
version: '1.0.1',
summary: 'Accounts login for LDAP using ldapjs. Supports anonymous DN search & LDAPS.',
git: 'https://github.com/typ90/meteor-accounts-ldap',
documentation: 'README.md'
});
Package.onUse(function(api) {
api.versionsFrom('1.0.3.1');
api.use(['templating'], 'client');
api.use(['typ:ldapjs@0.7.3'], 'server');
api.use('accounts-base', 'server');
api.imply('accounts-base');
api.imply('accounts-password');
api.use('check');
api.addFiles(['ldap_client.js'], 'client');
api.addFiles(['ldap_server.js'], 'server');
api.export('LDAP', 'server');
api.export('LDAP_DEFAULTS', 'server');
});

View File

@ -1,15 +0,0 @@
## clinical:themes
Theme selection component for ClinicalFramework apps.
------------------------
### Installation
````
meteor add clinical:themes
````
------------------------
### License
MIT License. Use as you wish, including for commercial purposes.

View File

@ -1,31 +0,0 @@
Package.describe({
name: 'clinical:themes',
version: '0.0.1',
// Brief, one-line summary of the package.
summary: 'Theme selection component for ClinicalFramework apps.',
// URL to the Git repository containing the source code for this package.
git: 'https://github.com/awatson1978/clinical-themes',
// By default, Meteor will default to using README.md for documentation.
// To avoid submitting documentation, set this field to null.
documentation: 'README.md'
});
Package.onUse(function (api) {
api.versionsFrom('1.2.1');
api.use('meteor-platform');
api.use('less');
api.addFiles('lib/ActiveThemes.js');
api.addFiles('components/themeCard.html');
api.addFiles('components/themeCard.js');
api.addFiles('components/themeCard.less');
});
Package.onTest(function (api) {
api.use('tinytest');
api.use('clinical:themes');
api.addFiles('tests/clinical-themes.js');
});

View File

@ -1,10 +0,0 @@
// Write your tests here!
// Here is an example.
describe('clinical:collaborations-ui', function () {
it.client('runs only in client', function () {
expect(Meteor.isClient).to.be.true;
});
it.server('runs only in server', function () {
expect(Meteor.isServer).to.be.true;
});
});

View File

@ -1 +0,0 @@
.build*

View File

@ -1,84 +0,0 @@
## clinical:ui-vocabulary
Package to provide semantic CSS classes to your app. Based on Bootstrap3.
=========================
#### Installation
Simply nstall the clinical-ui-vocabulary package from the command line, like so:
````js
meteor add clinical:ui-vocabulary
````
Then feel free to use the following CSS classes in your application.
=========================
#### Vocabulary - Anchoring
- fixed-layout
- left-anchored
- right-anchored
- bottom-anchored
- top-anchored
- right-aligned
- left-aligned
- absolute-layout
- fixed-layout
=========================
#### Vocabulary - Borders
- gray-border
- with-rounded-corners
=========================
#### Vocabulary - Fonts
- monospace
=========================
#### Vocabulary - Haptics
- clickable
- unselectable
=========================
#### Vocabulary - Padding
- well-behaved
- padded
- padded-horizontal, with-horizontal-padding, horizontally-padded
- padded-vertical, with-vertical-padding, vertically-padded
- with-right-padding
- with-left-padding
- without-padding, nopadding, no-padding
- without-right-padding
- without-left-padding
- without-top-padding
- without-bottom-padding
- without-vertical-padding
- without-horizontal-padding
=========================
#### Vocabulary - Colors
- dark
- light
- white
- black
- gray
- lightgray
- darkgray
- transparent
- glass
- fog
- mostly-opaque
- red
- blue
- green
- maroon
- etc

View File

@ -1,56 +0,0 @@
//---------------------------------
// layouts
.absolute-layout{
position:absolute;
}
.fixed-layout{
position: fixed;
}
//---------------------------------
// anchoring
.left-anchored{
position: fixed;
left: 0px;
}
.right-anchored{
position: fixed;
right: 0px;
}
.float-right{
position: absolute;
float: right;
right: 0px;
}
.bottom-anchored{
position: fixed;
bottom: 0px;
}
.top-anchored{
position: fixed;
top: 0px;
}
// alignment
.right-aligned{
text-align: right;
}
.left-aligned{
text-align: left;
}
// layouts
.absolute-layout{
position:absolute;
}
.fixed-layout{
position: fixed;
}

View File

@ -1,6 +0,0 @@
.with-rounded-corners {
-moz-border-radius: .4em;
-webkit-border-radius: .4em;
border-radius: .4em;
}

View File

@ -1,66 +0,0 @@
.dark{
color: white;
background-color: black;
}
.light{
color: black;
background-color: white;
}
.maroon{
color: #6B1A2C;
}
.green{
color: green;
}
.red{
color: red;
}
.blue{
color: blue;
}
.yellow{
color: yellow;
}
.purple{
color: purple;
}
.orange{
color: orange;
}
.black{
color: black;
}
.white{
color: white;
}
.gray{
color: gray;
}
.lightgray{
color: lightgray;
}
.darkgray{
color: darkgray;
}
.notepad{
background-color: lightyellow;
}
.transparent{
opacity: 0.3;
}
.glass{
opacity: 0.8;
background: lightgray;
}
.fog{
opacity: 0.8;
background: gray;
}
.mostly-opaque{
opacity: 0.2;
}
.mostly-transparent{
}

View File

@ -1,3 +0,0 @@
.monospace{
font-family:Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace;
}

View File

@ -1,13 +0,0 @@
//-----------------------------------------
// Clicking
.clickable{
cursor: pointer;
}
.unselectable{
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}

View File

@ -1,27 +0,0 @@
Package.describe({
summary: "UI vocabulary for ClinicalFramework.",
version: "1.0.5",
git: "http://github.com/awatson1978/clinical-ui-vocabulary.git",
name: "clinical:ui-vocabulary"
});
Package.onUse(function(api) {
api.versionsFrom('1.2.1');
api.use('ian:bootstrap-3@3.3.1');
api.addFiles('anchoring.less', 'client');
api.addFiles('borders.less', 'client');
api.addFiles('colors.less', 'client');
api.addFiles('fonts.less', 'client');
api.addFiles('haptics.less', 'client');
api.addFiles('padding.less', 'client');
api.addFiles('pages.less', 'client');
api.addFiles('sizing.less', 'client');
api.addFiles('text.less', 'client');
});
Package.onTest(function(api) {
api.use('tinytest');
});

View File

@ -1,111 +0,0 @@
.well-behaved{
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
//-----------------------------------------
// Padding
.padded{
box-sizing: border-box;
padding: 20px;
}
.padded-horizontal, .with-horizontal-padding, .horizontally-padded{
box-sizing: border-box;
padding-left: 20px;
padding-right: 20px;
}
.padded-vertical, .with-vertical-padding, .vertically-padded{
box-sizing: border-box;
padding-top: 20px;
padding-bottom: 20px;
}
.with-right-padding{
padding-right: 20px !important;
}
.with-left-padding{
padding-left: 20px !important;
}
//-----------------------------------------
// Without Padding
.without-padding, .nopadding, .no-padding{
padding: 0px;
}
.without-right-padding{
padding-right: 0px !important;
}
.without-left-padding{
padding-left: 0px !important;
}
.without-top-padding{
padding-top: 0px !important;
}
.without-bottom-padding{
padding-bottom: 0px !important;
}
.without-vertical-padding{
padding-top: 0px !important;
padding-bottom: 0px !important;
}
.without-vertical-padding{
padding-left: 0px !important;
padding-right: 0px !important;
}
//-----------------------------------------
// Spacers
.with-bottom-spacer, .with-bottom-padding{
padding-bottom: 20px !important;
}
.with-top-spacer, .with-top-padding{
padding-top:20px !important;
}
.with-right-spacer{
margin-right: 5px !important;
}
.with-right-spacer{
margin-left: 5px !important;
}
//-----------------------------------------
// Margins
.margined, .with-margins{
margin-left: 20px;
margin-right: 20px;
margin-top: 20px;
margin-bottom: 20px;
}
.with-bottom-margin{
margin-bottom: 20px !important;
}
.with-top-margin{
margin-top:20px !important;
}
.with-right-margin{
margin-right: 20px !important;
}
.with-left-margin{
margin-left:20px !important;
}
//-----------------------------------------
// Margins
.spacer{
height: 20px;
}

View File

@ -1,4 +0,0 @@
.page{
padding-top: 50px;
padding-bottom: 50px;
}

View File

@ -1,10 +0,0 @@
//-----------------------------------------
// Sizing
.fullwidth{
width: 100%;
}
.fullheight{
height: 100%;
}

View File

@ -1,36 +0,0 @@
//-----------------------------------------
// Text and Fonts
.bold{
font-weight: bold;
}
.centered{
text-align: center;
}
.strikeout{
text-decoration: line-through;
color: lightgray !important;
}
.dotted{
border-style: dotted;
border-width: 2px;
border-color: lightgray;
}
.strikeout{
text-decoration: line-through;
color: lightgray !important;
}
.hidden{
visibility: hidden;
display: none;
}
.visible{
visibility: visible;
display: block;
}
.largish{
font-size: 32px;
}

View File

@ -1,27 +0,0 @@
{
"dependencies": [
[
"ian:bootstrap-3",
"3.3.1"
],
[
"jquery",
"1.0.1"
],
[
"less",
"1.0.11"
],
[
"meteor",
"1.1.3"
],
[
"underscore",
"1.0.1"
]
],
"pluginDependencies": [],
"toolVersion": "meteor-tool@1.0.35",
"format": "1.0"
}

View File

@ -1,5 +0,0 @@
// The list of the known DICOM modalities
// If you are running Orthanc , you need to put the contents of this file in its Configuration file
"DicomModalities" : {
"OHIFDCM" : [ "OHIFDCM", "localhost", 3000 ]
},

View File

@ -55,7 +55,12 @@ var getInstanceRetrievalParams = function(studyInstanceUID, seriesInstanceUID) {
};
Meteor.startup(function() {
if (!Meteor.settings.servers.dimse || !Meteor.settings.servers.dimse.length) {
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.');
}

View File

@ -1,15 +1,17 @@
Servers = new Mongo.Collection('servers');
Timepoints = new Meteor.Collection('timepoints');
Studies = new Meteor.Collection('studies');
Measurements = new Meteor.Collection('measurements');
import { Mongo } from 'meteor/mongo';
Timepoints = new Mongo.Collection('timepoints');
Studies = new Mongo.Collection('studies');
Measurements = new Mongo.Collection('measurements');
// ImageMeasurements describe temporary measurements that aren't
// specifically listed in the Lesion Table
ImageMeasurements = new Meteor.Collection('imageMeasurements');
ImageMeasurements = new Mongo.Collection('imageMeasurements');
// Additional Findings stores details from the Additional Findings
// panel, and represents items such as data quality,
AdditionalFindings = new Meteor.Collection('additionalFindings');
AdditionalFindings = new Mongo.Collection('additionalFindings');
Servers = new Mongo.Collection('servers');
WorklistSubscriptions = ['studies', 'timepoints'];
Reviewers = new Meteor.Collection('reviewers');
Reviewers = new Mongo.Collection('reviewers');

View File

@ -19,11 +19,13 @@ TrialCriteriaConstraints = {
*/
function RECIST(image) {
var acquisitionSliceThickness;
var isChestXray;
if (image) {
acquisitionSliceThickness = image.acquisitionSliceThickness;
// TODO: Use metaData to determine if this is a chest X-ray
var isChestXray = false;
isChestXray = false;
}
// Define the RECIST 1.1 structure

View File

@ -109,7 +109,7 @@ activateLesion = function(measurementId, templateData) {
// Otherwise, re-render the viewport with the required study/series, then
// add an onRendered callback to activate the measurements
rerenderViewportWithNewSeries(element, requiredSeriesData, function(element) {
layoutManager.rerenderViewportWithNewDisplaySet(element, requiredSeriesData, function(element) {
activateMeasurements(element, measurementId, templateData, viewportIndex);
});
});

View File

@ -5,7 +5,7 @@ Package.describe({
});
Package.onUse(function(api) {
api.versionsFrom('1.3.5.1');
api.versionsFrom('1.4');
api.use('ecmascript');
api.use('standard-app-packages');
@ -189,19 +189,6 @@ Package.onUse(function(api) {
api.addFiles('client/components/lesionTrackerViewportOverlay/lesionTrackerViewportOverlay.html', 'client');
api.addFiles('client/components/lesionTrackerViewportOverlay/lesionTrackerViewportOverlay.js', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationDicomWeb.html', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationDicomWeb.js', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationDimse.html', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationDimse.js', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationForm.html', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationForm.js', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationFormField.html', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationList.html', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationList.js', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationModal.html', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationModal.styl', 'client');
api.addFiles('client/components/serverInformationModal/serverInformationModal.js', 'client');
api.addFiles('client/components/userAccountMenu/userAccountMenu.html', 'client');
api.addFiles('client/components/userAccountMenu/userAccountMenu.styl', 'client');
api.addFiles('client/components/userAccountMenu/userAccountMenu.js', 'client');
@ -213,10 +200,10 @@ Package.onUse(function(api) {
api.addFiles('client/components/lastLoginModal/lastLoginModal.js', 'client');
// Server functions
api.addFiles('server/collections.js', 'server');
api.addFiles('server/removeCollections.js', [ 'server' ]);
api.addFiles('server/reviewers.js', [ 'server' ]);
api.addFiles('server/servers.js', 'server');
api.addFiles('server/publications.js', 'server');
api.addFiles('server/methods.js', [ 'server' ]);
api.addFiles('server/reviewers.js', [ 'server' ]);
// Both client and server functions
api.addFiles('both/collections.js', [ 'client', 'server' ]);
@ -252,6 +239,23 @@ Package.onUse(function(api) {
api.addFiles('lib/handleMeasurementModified.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.addFiles('lib/api/timepoint.js');
@ -291,8 +295,8 @@ Package.onUse(function(api) {
api.export('TrialCriteriaTypes', 'client');
// Export collections spanning both client and server
api.export('AdditionalFindings', [ 'client', 'server' ]);
api.export('Servers', [ 'client', 'server' ]);
api.export('AdditionalFindings', [ 'client', 'server' ]);
api.export('ImageMeasurements', [ 'client', 'server' ]);
api.export('Measurements', [ 'client', 'server' ]);
api.export('Studies', [ 'client', 'server' ]);

View File

@ -46,7 +46,7 @@ Meteor.publish('reviewers', function() {
return Reviewers.find();
});
Meteor.publish('servers', function() {
Meteor.publish('servers', () => {
return Servers.find();
});

View File

@ -1,5 +1,7 @@
Meteor.startup(function() {
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
Meteor.startup(function() {
_.each(Meteor.settings.servers, function(endpoints, serverType) {
_.each(endpoints, function(endpoint) {
var server = _.clone(endpoint);
@ -8,7 +10,6 @@ Meteor.startup(function() {
Servers.insert(server);
});
});
});
class ServersControl {
@ -68,4 +69,4 @@ Meteor.methods({
serverSave: serverSettings => ServersControl.save(serverSettings),
serverSetActive: serverId => ServersControl.setActive(serverId),
serverRemove: serverId => ServersControl.remove(serverId)
});
});

View File

@ -1,6 +0,0 @@
.DS_Store
.npm
.build*
smart.lock
versions.json
.versions

View File

@ -1,3 +0,0 @@
v1.0.11 / 2015-10-09
==================
* Support Meteor 1.2

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2014 EventedMind <chris@eventedmind.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,18 +0,0 @@
Clinical Router MiddlewareStack
==============================================================================
Client and server middleware support inspired by Connect.
===============================
#### Installation
This package is a dependency of ``clinical:router``. Just install the router package, and you'll get this included.
````bash
meteor add clinical:router
````
===============================
#### Licensing
![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)

View File

@ -1,57 +0,0 @@
## Customize the test machine
machine:
# Timezone
timezone:
America/Los_Angeles # Set the timezone
# Add some environment variables
environment:
CIRCLE_ENV: test
CXX: g++-4.8
DISPLAY: :99.0
NPM_PREFIX: /home/ubuntu/nvm/v0.10.33
#general:
# build_dir: helloworld
## Customize dependencies
dependencies:
cache_directories:
- ~/.meteor # relative to the user's home directory
- ~/nvm/v0.10.33/lib/node_modules/starrynight
- ~/nvm/v0.10.33/bin/starrynight
pre:
# Install Starrynight unless it is cached
- if [ ! -e ~/nvm/v0.10.33/bin/starrynight ]; then npm install -g starrynight; else echo "Starrynight seems to be cached"; fi;
# Install Meteor
- mkdir -p ${HOME}/.meteor
# If Meteor is already cached, do not need to build it again.
- if [ ! -e ${HOME}/.meteor/meteor ]; then curl https://install.meteor.com | /bin/sh; else echo "Meteor seems to be cached"; fi;
# Link the meteor executable into /usr/bin
- sudo ln -s $HOME/.meteor/meteor /usr/bin/meteor
# Check if the helloworld directory already exists, if it doesn't, create the helloworld app
- if [ ! -e ${HOME}/helloworld ]; then meteor create --release METEOR@1.1.0.3 helloworld; else echo "helloworld app seems to be cached"; fi;
override:
- cd helloworld
- cd helloworld && ls -la
- cd helloworld && rm helloworld.*
- cd helloworld && meteor add anti:gagarin@0.4.11 session meteor-platform clinical:theming clinical:default-theme clinical:router clinical:router-default-config clinical:active-layout clinical:active-layout-reset clinical:active-layout-pagescreen-config grove:less
- cd helloworld && git clone http://github.com/clinical-meteor/router-middleware-stack packages/router-middleware-stack
- cd helloworld && meteor add clinical:router clinical:router-middleware-stack
- cd helloworld/packages && ls -la
- cd helloworld/packages/router-middleware-stack && ls -la
- cd helloworld/packages/router-middleware-stack/tests && ls -la
- cd helloworld/packages/router-middleware-stack/tests/gagarin && ls -la
- cd helloworld && starrynight autoconfig
## Customize test commands
test:
pre:
- cd helloworld && meteor:
background: true
- sleep 80
override:
- cd helloworld && starrynight run-tests --type package-verification

View File

@ -1 +0,0 @@
ofqtruq93rux231sdq

View File

@ -1,10 +0,0 @@
# Meteor packages used by this project, one per line.
#
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
standard-app-packages
autopublish
insecure
iron:middleware-stack

View File

@ -1,44 +0,0 @@
application-configuration@1.0.0
autopublish@1.0.0
autoupdate@1.0.0
binary-heap@1.0.0
blaze-tools@1.0.0
blaze@1.0.0
callback-hook@1.0.0
check@1.0.0
ctl-helper@1.0.0
ctl@1.0.0
deps@1.0.0
ejson@1.0.0
follower-livedata@1.0.0
geojson-utils@1.0.0
html-tools@1.0.0
htmljs@1.0.0
id-map@1.0.0
insecure@1.0.0
iron:core@0.1.0
iron:middleware-stack@0.1.0
iron:url@0.1.0
jquery@1.0.0
json@1.0.0
livedata@1.0.0
logging@1.0.0
meteor@1.0.0
minifiers@1.0.0
minimongo@1.0.0
mongo-livedata@1.0.1
observe-sequence@1.0.0
ordered-dict@1.0.0
random@1.0.0
reactive-dict@1.0.0
reload@1.0.0
retry@1.0.0
routepolicy@1.0.0
session@1.0.0
spacebars-compiler@1.0.0
spacebars@1.0.0
standard-app-packages@1.0.0
templating@1.0.0
ui@1.0.0
underscore@1.0.0
webapp@1.0.0

View File

@ -1,29 +0,0 @@
stack = new Iron.MiddlewareStack;
printUrls = function (name, thisArg) {
console.log('%c***********************', 'color: orange;');
console.log("<" + name + "> this.originalUrl: " + JSON.stringify(thisArg.originalUrl));
console.log("<" + name + "> this.url: " + JSON.stringify(thisArg.url));
console.log('%c***********************', 'color: orange;');
};
stack.push(function m1 () {
printUrls('m1', this);
this.next();
});
stack.push(function m2 () {
printUrls('m2', this);
this.next();
});
stack.push('/admin', function adminApp () {
printUrls('adminApp', this);
}, {mount: true});
console.log('%cDispatch "/"', 'color: blue;');
stack.dispatch('/', {});
console.log('');
console.log('%cDispatch "/admin"', 'color: blue;');
stack.dispatch('/admin', {});

View File

@ -1,118 +0,0 @@
var Url = Iron.Url;
Handler = function (path, fn, options) {
if (_.isFunction(path)) {
options = options || fn || {};
fn = path;
path = '/';
// probably need a better approach here to differentiate between
// Router.use(function () {}) and Router.use(MyAdminApp). In the first
// case we don't want to count it as a viable server handler when we're
// on the client and need to decide whether to go to the server. in the
// latter case, we DO want to go to the server, potentially.
this.middleware = true;
if (typeof options.mount === 'undefined')
options.mount = true;
}
// if fn is a function then typeof fn => 'function'
// but note we can't use _.isObject here because that will return true if the
// fn is a function OR an object.
if (typeof fn === 'object') {
options = fn;
fn = options.action || 'action';
}
options = options || {};
this.options = options;
this.mount = options.mount;
this.method = (options.method && options.method.toLowerCase()) || false;
// should the handler be on the 'client', 'server' or 'both'?
// XXX can't we default this to undefined in which case it's run in all
// environments?
this.where = options.where || 'client';
// if we're mounting at path '/foo' then this handler should also handle
// '/foo/bar' and '/foo/bar/baz'
if (this.mount)
options.end = false;
// set the name
if (options.name)
this.name = options.name;
else if (typeof path === 'string' && path.charAt(0) !== '/')
this.name = path;
else if (typeof path === 'string' && path !== '/')
this.name = path.split('/').slice(1).join('.');
// if the path is explicitly set on the options (e.g. legacy router support)
// then use that
// otherwise use the path argument which could also be a name
path = options.path || path;
if (typeof path === 'string' && path.charAt(0) !== '/')
path = '/' + path;
this.path = path;
this.compiledUrl = new Url(path, options);
if (_.isString(fn)) {
this.handle = function handle () {
// try to find a method on the current thisArg which might be a Controller
// for example.
var func = this[fn];
if (typeof func !== 'function')
throw new Error("No method named " + JSON.stringify(fn) + " found on handler.");
return func.apply(this, arguments);
};
} else if (_.isFunction(fn)) {
// or just a regular old function
this.handle = fn;
}
};
/**
* Returns true if the path matches the handler's compiled url, method
* and environment (e.g. client/server). If no options.method or options.where
* is provided, then only the path will be used to test.
*/
Handler.prototype.test = function (path, options) {
options = options || {};
var isUrlMatch = this.compiledUrl.test(path);
var isMethodMatch = true;
var isEnvMatch = true;
if (this.method && options.method)
isMethodMatch = this.method == options.method.toLowerCase();
if (options.where)
isEnvMatch = this.where == options.where;
return isUrlMatch && isMethodMatch && isEnvMatch;
};
Handler.prototype.params = function (path) {
return this.compiledUrl.params(path);
};
Handler.prototype.resolve = function (params, options) {
return this.compiledUrl.resolve(params, options);
};
/**
* Returns a new cloned Handler.
* XXX problem is here because we're not storing the original path.
*/
Handler.prototype.clone = function () {
var clone = new Handler(this.path, this.handle, this.options);
// in case the original function had a name
clone.name = this.name;
return clone;
};

View File

@ -1,282 +0,0 @@
var Url = Iron.Url;
var assert = Iron.utils.assert;
var defaultValue = Iron.utils.defaultValue;
/**
* Connect inspired middleware stack that works on the client and the server.
*
* You can add handlers to the stack for various paths. Those handlers can run
* on the client or server. Then you can dispatch into the stack with a
* given path by calling the dispatch method. This goes down the stack looking
* for matching handlers given the url and environment (client/server). If we're
* on the client and we should make a trip to the server, the onServerDispatch
* callback is called.
*
* The middleware stack supports the Connect API. But it also allows you to
* specify a context so we can have one context object (like a Controller) that
* is a consistent context for each handler function called on a dispatch.
*
*/
MiddlewareStack = function () {
this._stack = [];
this.length = 0;
};
MiddlewareStack.prototype._create = function (path, fn, options) {
var handler = new Handler(path, fn, options);
var name = handler.name;
if (name) {
if (_.has(this._stack, name)) {
throw new Error("Handler with name '" + name + "' already exists.");
}
this._stack[name] = handler;
}
return handler;
};
MiddlewareStack.prototype.findByName = function (name) {
return this._stack[name];
};
/**
* Push a new handler onto the stack.
*/
MiddlewareStack.prototype.push = function (path, fn, options) {
var handler = this._create(path, fn, options);
this._stack.push(handler);
this.length++;
return handler;
};
MiddlewareStack.prototype.append = function (/* fn1, fn2, [f3, f4]... */) {
var self = this;
var args = _.toArray(arguments);
var options = {};
if (typeof args[args.length-1] === 'object')
options = args.pop();
_.each(args, function (fnOrArray) {
if (typeof fnOrArray === 'undefined')
return;
else if (typeof fnOrArray === 'function')
self.push(fnOrArray, options);
else if (_.isArray(fnOrArray))
self.append.apply(self, fnOrArray.concat([options]));
else
throw new Error("Can only append functions or arrays to the MiddlewareStack");
});
return this;
};
/**
* Insert a handler at a specific index in the stack.
*
* The index behavior is the same as Array.prototype.splice. If the index is
* greater than the stack length the handler will be appended at the end of the
* stack. If the index is negative, the item will be inserted "index" elements
* from the end.
*/
MiddlewareStack.prototype.insertAt = function (index, path, fn, options) {
var handler = this._create(path, fn, options);
this._stack.splice(index, 0, handler);
this.length = this._stack.length;
return this;
};
/**
* Insert a handler before another named handler.
*/
MiddlewareStack.prototype.insertBefore = function (name, path, fn, options) {
var beforeHandler;
var index;
if (!(beforeHandler = this._stack[name]))
throw new Error("Couldn't find a handler named '" + name + "' on the path stack");
index = _.indexOf(this._stack, beforeHandler);
this.insertAt(index, path, fn, options);
return this;
};
/**
* Insert a handler after another named handler.
*
*/
MiddlewareStack.prototype.insertAfter = function (name, path, fn, options) {
var handler;
var index;
if (!(handler = this._stack[name]))
throw new Error("Couldn't find a handler named '" + name + "' on the path stack");
index = _.indexOf(this._stack, handler);
this.insertAt(index + 1, path, fn, options);
return this;
};
/**
* Return a new MiddlewareStack comprised of this stack joined with other
* stacks. Note the new stack will not have named handlers anymore. Only the
* handlers are cloned but not the name=>handler mapping.
*/
MiddlewareStack.prototype.concat = function (/* stack1, stack2, */) {
var ret = new MiddlewareStack;
var concat = Array.prototype.concat;
var clonedThisStack = EJSON.clone(this._stack);
var clonedOtherStacks = _.map(_.toArray(arguments), function (s) { return EJSON.clone(s._stack); });
ret._stack = concat.apply(clonedThisStack, clonedOtherStacks);
ret.length = ret._stack.length;
return ret;
};
/**
* Dispatch into the middleware stack, allowing the handlers to control the
* iteration by calling this.next();
*/
MiddlewareStack.prototype.dispatch = function dispatch (url, context, done) {
var self = this;
var originalUrl = url;
assert(typeof url === 'string', "Requires url");
assert(typeof context === 'object', "Requires context object");
url = Url.normalize(url || '/');
defaultValue(context, 'request', {});
defaultValue(context, 'response', {});
defaultValue(context, 'originalUrl', url);
//defaultValue(context, 'location', Url.parse(originalUrl));
defaultValue(context, '_method', context.method);
defaultValue(context, '_handlersForEnv', {client: false, server: false});
defaultValue(context, '_handled', false);
defaultValue(context, 'isHandled', function () {
return context._handled;
});
defaultValue(context, 'willBeHandledOnClient', function () {
return context._handlersForEnv.client;
});
defaultValue(context, 'willBeHandledOnServer', function () {
return context._handlersForEnv.server;
});
var wrappedDone = function () {
if (done) {
try {
done.apply(this, arguments);
} catch (err) {
// if we catch an error at this point in the stack we don't want it
// handled in the next() iterator below. So we'll mark the error to tell
// the next iterator to ignore it.
err._punt = true;
// now rethrow it!
throw err;
}
}
};
var index = 0;
var next = Meteor.bindEnvironment(function boundNext (err) {
var handler = self._stack[index++];
// reset the url
context.url = context.request.url = context.originalUrl;
if (!handler)
return wrappedDone.call(context, err);
if (!handler.test(url, {method: context._method}))
return next(err);
// okay if we've gotten this far the handler matches our url but we still
// don't know if this is a client or server handler. Let's track that.
// XXX couldn't the environment be something else like cordova?
var where = Meteor.isClient ? 'client' : 'server';
// track that we have a handler for the given environment so long as it's
// not middleware created like this Router.use(function () {}). We'll assume
// that if the handler is of that form we don't want to make a trip to
// the client or the server for it.
if (!handler.middleware)
context._handlersForEnv[handler.where] = true;
// but if we're not actually on that env, skip to the next handler.
if (handler.where !== where)
return next(err);
// get the parameters for this url from the handler's compiled path
// XXX removing for now
//var params = handler.params(context.location.href);
//context.request.params = defaultValue(context, 'params', {});
//_.extend(context.params, params);
// so we can call this.next()
// XXX this breaks with things like request.body which require that the
// iterator be saved for the given function call.
context.next = next;
if (handler.mount) {
var mountpath = Url.normalize(handler.compiledUrl.pathname);
var newUrl = url.substr(mountpath.length, url.length);
newUrl = Url.normalize(newUrl);
context.url = context.request.url = newUrl;
}
try {
//
// The connect api says a handler signature (arity) can look like any of:
//
// 1) function (req, res, next)
// 2) function (err, req, res, next)
// 3) function (err)
var arity = handler.handle.length
var req = context.request;
var res = context.response;
// function (err, req, res, next)
if (err && arity === 4)
return handler.handle.call(context, err, req, res, next);
// function (req, res, next)
if (!err && arity < 4)
return handler.handle.call(context, req, res, next);
// default is function (err) so punt the error down the stack
// until we either find a handler who likes to deal with errors or we call
// out
return next(err);
} catch (err) {
if (err._punt)
// ignore this error and throw it down the stack
throw err;
else
// see if the next handler wants to deal with the error
next(err);
} finally {
// we'll put this at the end because some middleware
// might want to decide what to do based on whether we've
// been handled "yet". If we set this to true before the handler
// is called, there's no way for the handler to say, if we haven't been
// handled yet go to the server, for example.
context._handled = true;
context.next = null;
}
});
next();
context.next = null;
return context;
};
Iron = Iron || {};
Iron.MiddlewareStack = MiddlewareStack;

View File

@ -1,32 +0,0 @@
Package.describe({
name: 'clinical:router-middleware-stack',
summary: 'Client and server middleware support inspired by Connect.',
version: '2.1.2',
git: 'https://github.com/clinical-meteor/clinical-router-middleware-stack'
});
Package.on_use(function (api) {
api.versionsFrom('1.1.0.3');
api.use('underscore');
api.use('ejson');
api.use('iron:core@1.0.11');
api.imply('iron:core');
api.use('clinical:router-url@2.1.0');
api.add_files('lib/handler.js');
api.add_files('lib/middleware_stack.js');
api.export('MiddlewareStack');
api.export('Handler', {testOnly: true});
});
Package.on_test(function (api) {
api.use('clinical:router-middleware-stack');
api.use('tinytest');
api.use('test-helpers');
api.add_files('tests/tinytests/handler_test.js');
api.add_files('tests/tinytests/middleware_stack_test.js');
});

View File

@ -1,17 +0,0 @@
describe('clinical:router-middleware-stack', function () {
var server = meteor();
var client = browser(server);
it('MiddlewareStack should exist on the client', function () {
return client.execute(function () {
expect(MiddlewareStack).to.exist;
});
});
it('MiddlewareStack should exist on the client', function () {
return server.execute(function () {
expect(MiddlewareStack).to.exist;
});
});
});

View File

@ -1,54 +0,0 @@
Tinytest.add('MiddlewareStack - handler basics', function (test) {
var handler;
var fn = function myName () {};
var opts = {};
// constructor options
// middleware handler
handler = new Handler(fn);
test.equal(handler.handle, fn);
test.equal(handler.name, 'myName', 'name is "myName"');
test.equal(handler.where, 'client');
test.isTrue(handler.test('/'));
test.isTrue(handler.test('/match/everything'));
opts.name = 'newName';
handler = new Handler('/items/:id', fn, opts);
test.equal(handler.handle, fn);
test.equal(handler.name, 'newName', 'name is "newName"');
test.equal(handler.options, opts);
test.isTrue(handler.test('/items/1'));
test.isTrue(handler.test('/items/2'));
handler = new Handler('/items/:id?', fn, opts);
test.isTrue(handler.test('/items/1'));
test.isTrue(handler.test('/items'));
handler = new Handler(/.*/, fn, opts);
test.isTrue(handler.test('/'));
test.isTrue(handler.test('/foo'));
var called = false;
var thisArg = {
methodName: function () {called = true;}
};
handler = new Handler('/items/:id', 'methodName');
handler.handle.call(thisArg);
test.isTrue(called);
handler = new Handler('/items/:id', fn);
var params = handler.params('/items/5');
test.equal(params.id, "5");
});
Tinytest.add('Handler - test', function (test) {
var handler = new Handler('/testme', function () {}, {
where: 'server',
method: 'GET'
});
test.isTrue(handler.test('/testme', {where: 'server', method: 'GET'}));
test.isFalse(handler.test('/testme', {where: 'client', method: 'GET'}));
test.isFalse(handler.test('/testme', {where: 'server', method: 'POST'}));
});

View File

@ -1,182 +0,0 @@
Tinytest.add('MiddlewareStack - handler names and paths', function (test) {
var handler;
// path is a name
handler = new Handler('home', {});
test.equal(handler.name, 'home', 'name is "home"');
test.equal(handler.path, '/home', 'path is "/home"');
// path is an option
handler = new Handler('home', {path: '/foo'});
test.equal(handler.name, 'home', 'name is "home"');
test.equal(handler.path, '/foo', 'path is "/foo"');
handler = new Handler('/home', {path: '/bar'});
test.equal(handler.path, '/bar', 'path is "/bar"');
handler = new Handler('/home', {path: '/bar', name: 'foo'});
test.equal(handler.path, '/bar', 'path is "/bar"');
test.equal(handler.name, 'foo', 'name is "foo"');
});
Tinytest.add('MiddlewareStack - create and find by name', function (test) {
// basically just test that a handler gets created and keyed by name if thee's
// a name. Also test duplicate named handlers throws an error.
var stack = new Iron.MiddlewareStack;
stack._create('/items', function () {}, {name: 'items'});
test.isTrue(stack.findByName('items'));
test.throws(function () {
// same name
stack._create('/items', function () {}, {name: 'items'});
});
});
Tinytest.add('MiddlewareStack - push', function (test) {
var stack = new Iron.MiddlewareStack;
var fns = [function () {}, function () {}];
stack.push(fns[0]);
test.equal(stack._stack[0].handle, fns[0]);
stack.push(fns[1]);
test.equal(stack._stack[1].handle, fns[1]);
});
Tinytest.add('MiddlewareStack - insertAt', function (test) {
var stack = new Iron.MiddlewareStack;
var fns = [function () {}, function () {}, function () {}];
stack.push(fns[0]);
stack.push(fns[2]);
stack.insertAt(1, fns[1]);
test.equal(stack._stack[1].handle, fns[1]);
});
Tinytest.add('MiddlewareStack - insertBefore', function (test) {
var stack = new Iron.MiddlewareStack;
var fns = [function one() {}, function two() {}, function three() {}];
stack.push(fns[0]);
stack.push(fns[2]);
stack.insertBefore('three', fns[1]);
test.equal(stack._stack[1].handle, fns[1]);
});
Tinytest.add('MiddlewareStack - insertAfter ', function (test) {
var stack = new Iron.MiddlewareStack;
var fns = [function one() {}, function two() {}, function three() {}];
stack.push(fns[0]);
stack.push(fns[2]);
stack.insertAfter('one', fns[1]);
test.equal(stack._stack[1].handle, fns[1]);
});
Tinytest.add('MiddlewareStack - dispatch iteration with this.next', function (test) {
var stack = new Iron.MiddlewareStack;
var calls = [];
if (Meteor.isClient) {
stack.push(function m1 () {
calls.push('m1');
this.next();
});
stack.push(function m2 () {
calls.push('m2');
// no call to next
});
stack.push(function m3 () {
calls.push('m3');
});
stack.dispatch('/', {});
test.equal(calls.length, 2, "call length is two");
test.equal(calls[0], 'm1', "m1 called");
test.equal(calls[1], 'm2', "m2 called");
}
if (Meteor.isServer) {
stack.push(function m1 () {
calls.push('m1');
this.next();
}, {where: 'server'});
stack.push(function m2 () {
calls.push('m2');
// no call to next
}, {where: 'server'});
stack.push(function m3 () {
calls.push('m3');
}, {where: 'server'});
stack.dispatch('/', {});
test.equal(calls.length, 2, "call length is two");
test.equal(calls[0], 'm1', "m1 called");
test.equal(calls[1], 'm2', "m2 called");
}
});
Tinytest.add('MiddlewareStack - dispatch callback', function (test) {
var stack = new Iron.MiddlewareStack;
var calls = [];
if (Meteor.isClient) {
stack.push(function m1 () {
calls.push('m1');
this.next();
});
stack.dispatch('/', {}, function () {
calls.push('done');
});
test.equal(calls.length, 2, "call length is two");
test.equal(calls[0], 'm1', "m1 called");
test.equal(calls[1], 'done', "done called");
}
if (Meteor.isServer) {
stack.push(function m1 () {
calls.push('m1');
this.next();
}, {where: 'server'});
stack.dispatch('/', {}, function () {
calls.push('done');
});
test.equal(calls.length, 2, "call length is two");
test.equal(calls[0], 'm1', "m1 called");
test.equal(calls[1], 'done', "done called");
}
});
if (Meteor.isServer) {
var Fiber = Npm.require('fibers');
Tinytest.addAsync('MiddlewareStack - async next maintains fibers', function (test, done) {
var envVar = new Meteor.EnvironmentVariable;
envVar.withValue(true, function () {
var stack = new Iron.MiddlewareStack;
test.isTrue(envVar.getOrNullIfOutsideFiber());
stack.push(function(req, res, next) {
// break out of the current fiber
setTimeout(function() {
next();
}, 0);
}, {where: 'server'});
stack.push(function(req, res, next) {
test.isTrue(envVar.getOrNullIfOutsideFiber());
this.next();
}, {where: 'server'});
stack.dispatch('/', {}, function () {
test.isTrue(envVar.getOrNullIfOutsideFiber());
done();
});
});
});
}

View File

@ -1,194 +0,0 @@
Tinytest.add('MiddlewareStack - dispatch', function (test) {
var stack = new Iron.MiddlewareStack;
var calls = {};
var call = function (name) {
calls[name] = calls[name] || 0;
calls[name]++;
};
// client middleware
stack.push(function m1 (req, res, next) {
call('m1');
next();
});
stack.push(function m2 (req, res, next) {
call('m2');
this.next();
});
// client handlers
var params;
stack.push('/items/:id', function item (req, res, next) {
call('item');
params = this.params;
next();
});
// same path is okay as long as name is different
stack.push('/items/:id', function itemTwo (req, res, next) {
call('item2');
});
// server handler
stack.push('/server', function server (req, res, next) {
call('server');
}, { where: 'server' });
var thisArg = {};
if (Meteor.isClient) {
stack.dispatch('/', {});
test.equal(calls.m1, 1, 'm1 not called');
test.equal(calls.m2, 1, 'm2 not called');
test.isFalse(calls.item);
test.isFalse(calls.item2);
test.isFalse(calls.server);
stack.dispatch('/items/1', thisArg);
test.equal(calls.m1, 2, 'm1 not called');
test.equal(calls.m2, 2, 'm2 not called');
test.equal(calls.item, 1, 'item not called');
test.equal(calls.item2, 1, 'item2 not called');
test.isFalse(calls.server);
var params = thisArg.params;
test.equal(params.id, "1");
stack.onServerDispatch(function () {
call('serverDispatch');
});
stack.dispatch('/server', {});
test.equal(calls.serverDispatch, 1);
}
if (Meteor.isServer) {
stack.dispatch('/server', {});
test.isFalse(calls.m1);
test.isFalse(calls.m2);
test.equal(calls.server, 1);
}
});
Tinytest.add('MiddlewareStack - dispatch error handling', function (test) {
if (Meteor.isClient) {
var stack = new Iron.MiddlewareStack;
var calls = [];
stack.push(function (req, res, next) {
calls.push(1);
throw new Error('test');
});
stack.push(function (req, res, next) {
calls.push(2);
next();
});
stack.dispatch('/', {
next: function (err) {
calls.push(3);
test.equal(err.message, 'test');
}
});
test.equal(calls.length, 2);
// first fn throws an error
test.equal(calls[0], 1);
// rest of middleware skipped
test.equal(calls[1], 3);
}
});
Tinytest.add('MiddlewareStack - mounting paths', function (test) {
var stack = new Iron.MiddlewareStack;
var calls = [];
if (Meteor.isClient) {
// add a mounted handler at mountpath /foo
stack.push('/foo', function (req, res, next) {
calls.push({args: EJSON.clone(arguments), thisArg: EJSON.clone(this)});
next();
}, {mount: true});
// add a regular handler at /foo/bar/baz
stack.push('/foo/bar/baz', function (req, res, next) {
calls.push({args: EJSON.clone(arguments), thisArg: EJSON.clone(this)});
});
stack.dispatch('/foo/bar/baz', {});
// make sure it got called
test.equal(calls.length, 2);
// this.url
test.equal(calls[0].thisArg.url, '/bar/baz', 'url wrong on controller');
test.equal(calls[0].thisArg.originalUrl, '/foo/bar/baz', 'originalUrl wrong on controller');
// fn (req, res, next)
// req.url
test.equal(calls[0].args[0].url, '/bar/baz', 'url wrong on req');
test.equal(calls[0].args[0].originalUrl, '/foo/bar/baz', 'originalUrl wrong on req');
// now make sure the url is set back to the originalUrl for non mounted
// handlers.
test.equal(calls[1].thisArg.url, '/foo/bar/baz');
test.equal(calls[1].thisArg.originalUrl, '/foo/bar/baz');
// fn (req, res, next)
// req.url
test.equal(calls[1].args[0].url, '/foo/bar/baz');
test.equal(calls[1].args[0].originalUrl, '/foo/bar/baz');
}
if (Meteor.isServer) {
stack.push('/foo', function (req, res, next) {
calls.push({args: EJSON.clone(arguments), thisArg: EJSON.clone(this)});
next();
}, {mount: true, where: 'server'});
// add a regular handler at /foo/bar/baz
stack.push('/foo/bar/baz', function (req, res, next) {
calls.push({args: EJSON.clone(arguments), thisArg: EJSON.clone(this)});
}, {where: 'server'});
stack.dispatch('/foo/bar/baz', {});
// make sure it got called
test.equal(calls.length, 2);
// this.url
test.equal(calls[0].thisArg.url, '/bar/baz');
test.equal(calls[0].thisArg.originalUrl, '/foo/bar/baz');
// fn (req, res, next)
// req.url
test.equal(calls[0].args[0].url, '/bar/baz');
test.equal(calls[0].args[0].originalUrl, '/foo/bar/baz');
// now make sure the url is set back to the originalUrl for non mounted
// handlers.
test.equal(calls[1].thisArg.url, '/foo/bar/baz');
test.equal(calls[1].thisArg.originalUrl, '/foo/bar/baz');
// fn (req, res, next)
// req.url
test.equal(calls[1].args[0].url, '/foo/bar/baz');
test.equal(calls[1].args[0].originalUrl, '/foo/bar/baz');
}
});
Tinytest.add('MiddlewareStack - append with options', function (test) {
var fn1 = function () {};
var fn2 = function () {};
var stack = new Iron.MiddlewareStack;
stack.append(fn1, fn2, {where: 'server'});
test.equal(stack._stack[0].where, 'server');
test.equal(stack._stack[1].where, 'server');
});
//TODO concat
//TODO append

View File

@ -63,7 +63,7 @@ errorLoadingHandler = function(element, imageId, error, source) {
};
Template.loadingIndicator.helpers({
'percentComplete': function(e) {
'percentComplete'() {
var percentComplete = Session.get('CornerstoneLoadProgress' + this.viewportIndex);
if (percentComplete && percentComplete !== 100) {
return percentComplete + '%';

View File

@ -1,25 +0,0 @@
//import {validate} from '../client/compatibility/validate.js';
validate.validators.equals = function(value, options, key, attributes) {
if (options && value !== options.value) {
return key + 'must equal ' + options.value;
}
};
validate.validators.doesNotEqual = function(value, options, key) {
if (options && value === options.value) {
return key + 'cannot equal ' + options.value;
}
};
validate.validators.contains = function(value, options, key) {
if (options && value.indexOf && value.indexOf(options.value) === -1) {
return key + 'must contain ' + options.value;
}
};
validate.validators.doesNotContain = function(value, options, key) {
if (options && value.indexOf && value.indexOf(options.value) !== -1) {
return key + 'cannot contain ' + options.value;
}
};

View File

@ -144,7 +144,6 @@ Package.onUse(function(api) {
api.addFiles('lib/setFocusToActiveViewport.js', 'client');
api.addFiles('lib/updateAllViewports.js', 'client');
//api.addFiles('lib/validators.js', 'client');
api.addFiles('lib/instanceClassSpecificViewport.js', 'client');
api.addFiles('lib/setMammogramViewportAlignment.js', 'client');
api.addFiles('lib/isImage.js', 'client');

View File

@ -1 +1,3 @@
StudyImportStatus = new Meteor.Collection('studyImportStatus');
import { Mongo } from 'meteor/mongo';
StudyImportStatus = new Mongo.Collection('studyImportStatus');

View File

@ -4,6 +4,7 @@ export const DICOMWebRequestOptions = new SimpleSchema({
auth: {
type: String,
label: 'Username:Password Authentication String',
optional: true
},
logRequests: {
type: Boolean,

View File

@ -69,7 +69,7 @@ Package.onUse(function (api) {
api.addFiles('client/components/progressDialog/progressDialog.html', 'client');
api.addFiles('client/components/progressDialog/progressDialog.styl', 'client');
api.addFiles('client/components/progressDialog/progressDialog.js', 'client');
// Client-side library functions
api.addFiles('client/lib/getStudyMetadata.js', 'client');
api.addFiles('client/lib/getStudiesMetadata.js', 'client');
@ -81,14 +81,17 @@ Package.onUse(function (api) {
api.addFiles('client/lib/importStudies.js', 'client');
// Server-side functions
api.addFiles('server/collections.js', 'server');
api.addFiles('server/publications.js', 'server');
api.addFiles('server/validateServerConfiguration.js', 'server');
api.addFiles('server/lib/namespace.js', 'server');
api.addFiles('server/lib/remoteGetValue.js', 'server');
api.addFiles('server/lib/encodeQueryData.js', 'server');
api.addFiles('server/methods/getStudyMetadata.js', 'server');
api.addFiles('server/methods/importStudies.js', 'server');
api.addFiles('server/methods/worklistSearch.js', 'server');
api.addFiles('server/services/namespace.js', 'server');
// DICOMWeb instance, study, and metadata retrieval
api.addFiles('server/services/qido/instances.js', 'server');
api.addFiles('server/services/qido/studies.js', 'server');

View File

@ -1,3 +0,0 @@
Meteor.publish('studyImportStatus', function() {
return StudyImportStatus.find();
});

View File

@ -0,0 +1,3 @@
export const remoteGetValue = function(obj) {
return obj ? obj.Value : null;
};

View File

@ -1,3 +1,5 @@
import { StudyImportStatus } from '../../both/collections';
var fs = Npm.require('fs');
var fiber = Npm.require('fibers');

View File

@ -0,0 +1,5 @@
import { StudyImportStatus } from '../both/collections';
Meteor.publish('studyImportStatus', () => {
return StudyImportStatus.find();
});

View File

@ -1,3 +1,5 @@
import { remoteGetValue } from '../../lib/remoteGetValue';
/**
* Parses data returned from a QIDO search and transforms it into
* an array of series that are present in the study

View File

@ -1,3 +1,5 @@
import { remoteGetValue } from '../../lib/remoteGetValue';
/**
* Parses the SourceImageSequence, if it exists, in order
* to return a ReferenceSOPInstanceUID. The ReferenceSOPInstanceUID

View File

@ -1,3 +1,5 @@
import { remoteGetValue } from '../../lib/remoteGetValue';
function resultDataToStudies(resultData) {
var studies = [];

View File

@ -1,31 +0,0 @@
{
"servers": {
"dicomWeb": [
{
"name": "DCM4CHE",
"wadoUriRootNOTE": "either this uri is not correct for wado-uri or wado-uri is not configured on orthanc currently",
"wadoUriRoot": "http://192.168.99.100:8080/dcm4chee-arc/aets/DCM4CHEE/wado",
"qidoRoot": "http://192.168.99.100:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
"wadoRoot": "http://192.168.99.100:8080/dcm4chee-arc/aets/DCM4CHEE/rs/wado/DCM4CHEE",
"qidoSupportsIncludeField": true,
"imageRendering": "wadouri",
"requestOptions": {
"logRequests": true,
"logResponses": false,
"logTiming": true
}
}
],
"dimse": [
{
"name": "DCM4CHE_DIMSE",
"peers": [{
"host": "192.168.99.100",
"port": 11112,
"hostAE": "DCM4CHE"
}]
}
]
},
"defaultServiceType": "dicomWeb"
}

View File

@ -1,19 +0,0 @@
{
"servers": {
"dicomWeb": [
{
"name": "Medical Connections",
"wadoUriRoot": "http://www.dicomserver.co.uk/wadouri",
"qidoRoot": "http://dicomserver.co.uk:81/qido",
"wadoRoot": "http://dicomserver.co.uk:81/wado",
"qidoSupportsIncludeField": false,
"imageRendering": "wadouri",
"requestOptions": {
"logRequests": true,
"logResponses": false,
"logTiming": true
}
}
]
}
}

View File

@ -3,8 +3,8 @@
"dicomWeb": [
{
"name": "Orthanc",
"wadoUriRootNOTE" : "either this uri is not correct for wado-uri or wado-uri is not configured on orthanc currently",
"wadoUriRoot" : "http://localhost:8043/wado",
"wadoUriRootNOTE": "either this uri is not correct for wado-uri or wado-uri is not configured on orthanc currently",
"wadoUriRoot": "http://localhost:8043/wado",
"qidoRoot": "http://localhost:8042/dicom-web",
"wadoRoot": "http://localhost:8042/dicom-web",
"qidoSupportsIncludeField": false,
@ -16,18 +16,13 @@
"logTiming": true
}
}
],
"dimse": [
{
"name": "ORTHANC_DIMSE",
"peers": [{
"host": "localhost",
"port": 4242,
"hostAE": "ORTHANC",
"aeTitle": "ORTHANC"
}]
}
]
},
"defaultServiceType": "dicomWeb"
"defaultServiceType": "dicomWeb",
"public": {
"verifyEmail": false,
"ui": {
"studyListFunctionsEnabled": true
}
}
}

View File

@ -1,39 +0,0 @@
{
"servers": {
"dicomWeb": [
{
"name": "SIIM DCM4CHEE",
"wadoUriRoot": "http://vna.hackathon.siim.org/dcm4chee-arc/wado/DCM4CHEE",
"qidoRoot": "http://vna.hackathon.siim.org/dcm4chee-arc/qido/DCM4CHEE",
"wadoRoot": "http://vna.hackathon.siim.org/dcm4chee-arc/wado/DCM4CHEE",
"qidoSupportsIncludeField": true,
"imageRendering": "wadouri",
"requestOptions": {
"logRequests": false,
"logResponses": false,
"logTiming": true
}
}
]
},
"defaultServiceType": "dicomWeb",
"public": {
"staleSessionInactivityTimeout": 300000,
"staleSessionHeartbeatInterval": 30000,
"staleSessionPurgeInterval": 15000,
"staleSessionActivityEvents": "mousemove click keydown",
"showCountdownDialog": true,
"dialogTimeout": 30000,
"verifyEmail": false
},
"mailServerSettings": {
"username": "",
"password": "",
"server": "",
"port": ""
},
"ldap": {
"url": "",
"port": ""
}
}

View File

@ -7,5 +7,5 @@ sed -i '' "s/localhost:8042/$MACHINEIP:8042/g" nodeCORSProxy.js
echo "Installing node http-proxy from npm..."
npm install http-proxy
echo "Running proxy server..."
echo "In a separate tab/terminal, go to /main and run ./bin/localhostOrthanc.sh to start the Meteor server"
echo "In a separate tab/terminal, go to /main and run ./bin/orthancDICOMWeb.sh to start the Meteor server"
node nodeCORSProxy.js