dbot-tripsit/tripsit/api.js

566 lines
20 KiB
JavaScript
Raw Normal View History

var _ = require('underscore'),
databank = require('databank'),
async = require('async');
var api = function(dbot) {
var api = {
'getDrugCategory': function(name, callback) {
name = name.toLowerCase();
this.db.read('drug_categories', name, function(err, cat) {
callback(cat);
});
},
'getIRCFormattedDrug': function(name, property, callback) {
this.api.getDrug(name, function(drug) {
if(drug && !_.has(drug, 'err')) {
if(_.has(drug, 'links') && _.has(drug.links, 'experiences')) {
drug.properties.experiences = drug.links.experiences;
}
if(!_.isUndefined(property)) {
if(_.has(drug.properties, property)) {
var info = drug.properties[property];
// TODO: Remove magic vars and move to formatProperty API func
if(property == 'dose') {
info = info.replace(/Threshold:/gi, "\u00032Threshold\u000f:");
info = info.replace(/Light:/gi, "\u00033Light\u000f:");
info = info.replace(/Common:/gi, "\u00037Common\u000f:");
info = info.replace(/Strong:/gi, "\u00035Strong\u000f:");
info = info.replace(/Heavy:/gi, "\u00034Heavy\u000f:");
}
if(property == 'aliases') info = info.join(', ');
callback(name + ' ' + property + ': ' + info);
} else {
callback(name + ' Info: ' + _.keys(drug.properties).join(', ') + ' - http://drugs.tripsit.me/' + drug.name);
}
} else {
callback(name + ' Info: ' + _.keys(drug.properties).join(', ') + ' - http://drugs.tripsit.me/' + drug.name);
}
} else {
callback(null);
}
});
},
'getInteraction': function(drugAName, drugBName, callback) {
drugAName = drugAName.toLowerCase();
drugBName = drugBName.toLowerCase();
if(drugAName == 'ssri' || drugAName == 'snri' || drugAName == 'snris') {
drugAName = 'ssris';
} else if(drugAName == 'maoi') {
drugAName = 'maois';
}
if(drugBName == 'ssri' || drugBName == 'snri' || drugBName == 'snris') {
drugBName = 'ssris';
} else if(drugBName == 'maoi') {
drugBName = 'maois';
}
this.api.getDrug(drugAName, function(drugA) {
if(!_.has(drugA, 'err') || _.has(this.combos, drugAName)) {
this.api.getDrug(drugBName, function(drugB) {
if(!_.has(drugB, 'err') || _.has(this.combos, drugBName)) {
var safetyCategoryA = null,
safetyCategoryB = null;
if(_.has(this.combos, drugAName)) {
safetyCategoryA = drugAName;
} else if(_.has(this.combos, drugA.name)) {
safetyCategoryA = drugA.name;
} else if(drugA.name.match(/^do.$/i)) {
safetyCategoryA = 'dox';
} else if(drugA.name.match(/^2c-.$/i)) {
safetyCategoryA = '2c-x';
} else if(drugA.name.match(/^25.-nbome/i)) {
safetyCategoryA = 'nbomes';
} else if(drugA.name.match(/^5-meo-..t$/i)) {
safetyCategoryA = '5-meo-xxt';
} else if(_.include(drugA.categories, 'benzodiazepine')) {
safetyCategoryA = 'benzodiazepines';
} else if(_.include(drugA.categories, 'opioid')) {
safetyCategoryA = 'opioids';
} else if(_.include(drugB.categories, 'benzo')) {
safetyCategoryB = 'benzos';
} else if(_.include(drugA.categories, 'stimulant')) {
safetyCategoryA = 'amphetamines';
} else if(drugA.name == 'ghb' || drugA.name == 'gbl') {
safetyCategoryA = 'ghb/gbl';
}
if(_.has(this.combos, drugBName)) {
safetyCategoryB = drugBName;
} else if(_.has(this.combos, drugB.name)) {
safetyCategoryB = drugB.name;
} else if(drugB.name.match(/^do.$/i)) {
safetyCategoryB = 'dox';
} else if(drugB.name.match(/^2c-.$/i)) {
safetyCategoryB = '2c-x';
} else if(drugB.name.match(/^25.-nbome/i)) {
safetyCategoryB = 'nbomes';
} else if(drugB.name.match(/^5-meo-..t$/i)) {
safetyCategoryB = '5-meo-xxt';
} else if(_.include(drugB.categories, 'benzodiazepine')) {
safetyCategoryB = 'benzodiazepines';
} else if(_.include(drugB.categories, 'opioid')) {
safetyCategoryB = 'opioids';
} else if(_.include(drugB.categories, 'benzo')) {
safetyCategoryB = 'benzos';
} else if(_.include(drugB.categories, 'stimulant')) {
safetyCategoryB = 'amphetamines';
} else if(drugB.name == 'ghb' || drugB.name == 'gbl') {
safetyCategoryB = 'ghb/gbl';
}
if(safetyCategoryA && safetyCategoryB) {
if(safetyCategoryA != safetyCategoryB) {
var result = _.clone(this.combos[safetyCategoryA][safetyCategoryB]);
result['interactionCategoryA'] = safetyCategoryA;
result['interactionCategoryB'] = safetyCategoryB;
return callback(result);
} else {
if(safetyCategoryA == 'benzodiazepines') {
return callback({'err': true, 'code': 'ssb', 'msg': 'Drug A and B are the same safety category.'});
} else {
return callback({'err': true, 'code': 'ssc', 'msg': 'Drug A and B are the same safety category.'});
}
}
} else {
return callback(false);
}
} else {
return callback({'err': true, 'msg': 'Drug B not found.'});
}
}.bind(this));
} else {
return callback({'err': true, 'msg': 'Drug A not found.'});
}
}.bind(this));
},
'getDrug': function(name, callback) {
name = name.toLowerCase();
this.db.read('drugs', name, function(err, drug) {
if(!drug) {
this.db.scan('drugs', function(dMatch) {
if(_.include(dMatch.aliases, name)) {
drug = dMatch;
if(!_.isUndefined(drug.aliases)) drug.properties.aliases = drug.aliases;
}
}, function() {
if(drug) {
if(!_.isUndefined(drug.aliases)) drug.properties.aliases = drug.aliases;
if(!_.isUndefined(drug.categories)) drug.properties.categories = drug.categories;
if(_.has(dbot.modules.tripsit.combos, drug.name)) {
drug.combos = dbot.modules.tripsit.combos[drug.name];
}
if(_.has(drug.properties, 'dose')) {
var doses = drug.properties.dose.split('|');
var regex = /(([\w-]+):\s([\/\.\w\d-\+µ]+))/ig;
drug.formatted_dose = {};
if(doses.length > 1 || !doses[0].split(' ')[0].match(':')) {
_.each(doses, function(dString) {
dString = dString.replace(/\s\s+/g, ' ');
var roa = dString.trim().split(' ')[0];
var match = regex.exec(dString);
if(roa.match(/note/i)) {
drug.dose_note = dString;
} else {
drug.formatted_dose[roa] = {};
while(match != null) {
drug.formatted_dose[roa][match[2]] = match[3];
match = regex.exec(dString);
}
}
});
} else {
var roa = 'Oral';
var match = regex.exec(doses[0]);
if(roa.match(/note/i)) {
drug.dose_note = doses[0];
} else {
drug.formatted_dose[roa] = {};
while(match != null) {
drug.formatted_dose[roa][match[2]] = match[3];
match = regex.exec(doses[0]);
}
}
}
}
if(_.has(drug.properties, 'effects')) {
drug.formatted_effects = _.collect(drug.properties.effects.split(/[\.,]+/), function(item) {
return item.trim();
});
}
if(_.has(drug.properties, 'duration')) {
var roas = drug.properties.duration.split('|');
drug.formatted_duration = {};
if(roas.length > 1 || roas[0].match(':')) {
_.each(roas, function(roa) {
if(roa.toLowerCase().match('note')) {
return;
}
var match = roa.match(/([\w-\/]+):?\s([\.\w\d-\+]+)/i);
if(match) {
drug.formatted_duration[match[1]] = match[2];
}
});
} else {
var match = drug.properties['duration'].match(/([\.\w\d-\+]+)/i);
drug.formatted_duration = {'value':match[1]};
}
if(drug.properties.duration.indexOf('minutes') != -1) {
drug.formatted_duration._unit = 'minutes';
}
if(drug.properties.duration.indexOf('hours') != -1) {
drug.formatted_duration._unit = 'hours';
}
}
if(_.has(drug.properties, 'onset')) {
var roas = drug.properties.onset.split('|');
drug.formatted_onset = {};
if(roas.length > 1 || roas[0].match(':')) {
_.each(roas, function(roa) {
if(roa.toLowerCase().match('note')) {
return;
}
var match = roa.match(/([\w-\/]+):?\s([\.\w\d-\+]+)/i);
if(match) {
drug.formatted_onset[match[1]] = match[2];
}
});
} else {
var match = drug.properties['onset'].match(/([\.\w\d-\+]+)/i);
drug.formatted_onset = {'value':match[1]};
}
if(drug.properties.onset.indexOf('minutes') != -1) {
drug.formatted_onset._unit = 'minutes';
}
if(drug.properties.onset.indexOf('hours') != -1) {
drug.formatted_onset._unit = 'hours';
}
}
if(_.has(drug.properties, 'after-effects')) {
var roas = drug.properties['after-effects'].split('|');
drug.formatted_aftereffects = {};
if(roas.length > 1 || roas[0].match(':')) {
_.each(roas, function(roa) {
if(roa.toLowerCase().match('note')) {
return;
}
var match = roa.match(/([\w\/]+):?\s([\.\w\d-\+]+)/i);
if(match) {
drug.formatted_aftereffects[match[1]] = match[2];
}
});
} else {
var match = drug.properties['after-effects'].match(/([\.\w\d-\+]+)/i);
drug.formatted_aftereffects = {'value':match[1]};
}
if(drug.properties['after-effects'].indexOf('minutes') != -1) {
drug.formatted_aftereffects._unit = 'minutes';
}
if(drug.properties['after-effects'].indexOf('hours') != -1) {
drug.formatted_aftereffects._unit = 'hours';
}
}
if(!_.has(drug, 'pretty_name')) {
drug.pretty_name = drug.name;
if(drug.name.length <= 4 || drug.name.indexOf('-') != -1) {
drug.pretty_name = drug.name.toUpperCase();
} else {
drug.pretty_name = drug.name.charAt(0).toUpperCase() + drug.name.slice(1);
}
drug.pretty_name = drug.pretty_name.replace(/MEO/, 'MeO');
drug.pretty_name = drug.pretty_name.replace(/ACO/, 'AcO');
drug.pretty_name = drug.pretty_name.replace(/NBOME/, 'NBOMe');
drug.pretty_name = drug.pretty_name.replace(/MIPT/, 'MiPT');
drug.pretty_name = drug.pretty_name.replace(/DIPT/, 'DiPT');
}
}
if(drug) {
callback(drug);
} else {
callback({'err': true, 'msg': 'No drug found.'});
}
});
} else {
if(drug) {
if(!_.isUndefined(drug.aliases)) drug.properties.aliases = drug.aliases;
if(!_.isUndefined(drug.categories)) drug.properties.categories = drug.categories;
if(_.has(dbot.modules.tripsit.combos, drug.name)) {
drug.combos = dbot.modules.tripsit.combos[drug.name];
}
if(_.has(drug.properties, 'dose')) {
var doses = drug.properties.dose.split('|');
var regex = /(([\w-]+):\s([\/\.\w\d-\+µ]+))/ig;
drug.formatted_dose = {};
if(doses.length > 1 || !doses[0].split(' ')[0].match(':')) {
_.each(doses, function(dString) {
dString = dString.replace(/\s\s+/g, ' ');
var roa = dString.trim().split(' ')[0];
var match = regex.exec(dString);
if(roa.match(/note/i)) {
drug.dose_note = dString;
} else {
drug.formatted_dose[roa] = {};
while(match != null) {
drug.formatted_dose[roa][match[2]] = match[3];
match = regex.exec(dString);
}
}
});
} else {
var roa = 'Oral';
var match = regex.exec(doses[0]);
if(roa.match(/note/i)) {
drug.dose_note = doses[0];
} else {
drug.formatted_dose[roa] = {};
while(match != null) {
drug.formatted_dose[roa][match[2]] = match[3];
match = regex.exec(doses[0]);
}
}
}
}
if(_.has(drug.properties, 'effects')) {
drug.formatted_effects = _.collect(drug.properties.effects.split(/[\.,]+/), function(item) {
return item.trim();
});
}
if(_.has(drug.properties, 'duration')) {
var roas = drug.properties.duration.split('|');
drug.formatted_duration = {};
if(roas.length > 1 || roas[0].match(':')) {
_.each(roas, function(roa) {
if(roa.toLowerCase().match('note')) {
return;
}
var match = roa.match(/([\w-\/]+):?\s([\.\w\d-\+]+)/i);
if(match) {
drug.formatted_duration[match[1]] = match[2];
}
});
} else {
var match = drug.properties['duration'].match(/([\.\w\d-\+]+)/i);
drug.formatted_duration = {'value':match[1]};
}
if(drug.properties.duration.indexOf('minutes') != -1) {
drug.formatted_duration._unit = 'minutes';
}
if(drug.properties.duration.indexOf('hours') != -1) {
drug.formatted_duration._unit = 'hours';
}
}
if(_.has(drug.properties, 'onset')) {
var roas = drug.properties.onset.split('|');
drug.formatted_onset = {};
if(roas.length > 1 || roas[0].match(':')) {
_.each(roas, function(roa) {
if(roa.toLowerCase().match('note')) {
return;
}
var match = roa.match(/([\/\w-]+):??\s([\.\w\d-\+]+)/i);
if(match) {
drug.formatted_onset[match[1]] = match[2];
}
});
} else {
var match = drug.properties['onset'].match(/([\.\w\d-\+]+)/i);
drug.formatted_onset = {'value':match[1]};
}
if(drug.properties.onset.indexOf('minutes') != -1) {
drug.formatted_onset._unit = 'minutes';
}
if(drug.properties.onset.indexOf('hours') != -1) {
drug.formatted_onset._unit = 'hours';
}
}
if(_.has(drug.properties, 'after-effects')) {
var roas = drug.properties['after-effects'].split('|');
drug.formatted_aftereffects = {};
if(roas.length > 1 || roas[0].match(':')) {
_.each(roas, function(roa) {
if(roa.toLowerCase().match('note')) {
return;
}
var match = roa.match(/([\w\/]+):?\s([\.\w\d-\+]+)/i);
if(match) {
drug.formatted_aftereffects[match[1]] = match[2];
}
});
} else {
var match = drug.properties['after-effects'].match(/([\.\w\d-\+]+)/i);
drug.formatted_aftereffects = {'value':match[1]};
}
if(drug.properties['after-effects'].indexOf('minutes') != -1) {
drug.formatted_aftereffects._unit = 'minutes';
}
if(drug.properties['after-effects'].indexOf('hours') != -1) {
drug.formatted_aftereffects._unit = 'hours';
}
}
if(!_.has(drug, 'pretty_name')) {
drug.pretty_name = drug.name;
if(drug.name.length <= 4 || drug.name.indexOf('-') != -1) {
drug.pretty_name = drug.name.toUpperCase();
} else {
drug.pretty_name = drug.name.charAt(0).toUpperCase() + drug.name.slice(1);
}
drug.pretty_name = drug.pretty_name.replace(/MEO/, 'MeO');
drug.pretty_name = drug.pretty_name.replace(/ACO/, 'AcO');
drug.pretty_name = drug.pretty_name.replace(/NBOME/, 'NBOMe');
drug.pretty_name = drug.pretty_name.replace(/MIPT/, 'MiPT');
drug.pretty_name = drug.pretty_name.replace(/DIPT/, 'DiPT');
}
}
if(drug) {
callback(drug);
} else {
callback({'err': true, 'msg': 'No drug found.'});
}
}
}.bind(this));
},
'getAllDrugNames': function(callback) {
var names = [];
this.db.scan('drugs', function(drug) {
if(drug) {
names.push(drug.name);
}
}, function() {
callback(names);
});
},
'getAllDrugNamesByCategory': function(category, callback) {
this.api.getAllDrugs(function(names) {
callback(_.pluck(_.filter(names, function(a) { return _.include(a.categories, category); }), 'name'));
});
},
'getAllDrugs': function(callback) {
this.api.getAllDrugNames(function(names) {
var drugs = {};
async.each(names, function(name, done) {
if(!_.isUndefined(name)) {
this.api.getDrug(name, function(drug) {
drugs[name] = drug;
done();
});
} else {
done();
}
}.bind(this), function() {
callback(drugs);
});
}.bind(this));
},
'getAllCategories': function(callback) {
var categories = {};
this.db.scan('drug_categories', function(cat) {
categories[cat.name] = cat;
}, function() {
callback(categories);
});
},
'getAllDrugAliases': function(callback) {
this.api.getAllDrugNames(function(names) {
var fullNames = [];
async.each(names, function(name, done) {
if(!_.isUndefined(name)) {
this.api.getDrug(name, function(drug) {
fullNames.push(name);
fullNames = _.union(fullNames, drug.aliases);
done();
});
} else {
done();
}
}.bind(this), function() {
callback(fullNames);
});
}.bind(this));
},
'delDrug': function(name, callback) {
this.db.del('drugs', name.toLowerCase(), function() {
callback();
});
},
'setDrugProperty': function(drug, property, content, callback) {
drug.properties[property] = content;
this.db.save('drugs', drug.name, drug, callback);
},
'setCategoryProperty': function(category, property, content, callback) {
category[property] = content;
this.db.save('drug_categories', category.name, category, callback);
},
'delDrugProperty': function(drug, property, callback) {
delete drug.properties[property];
this.db.save('drugs', drug.name, drug, callback);
},
'createDrug': function(name, callback) {
name = name.toLowerCase();
this.db.create('drugs', name, {
'name': name,
'properties': {}
}, callback);
}
};
api['getDrug'].external = true;
api['getDrug'].extMap = [ 'name', 'callback' ];
api['getAllDrugNames'].external = true;
api['getAllDrugNames'].extMap = [ 'callback' ];
api['getAllDrugNamesByCategory'].external = true;
api['getAllDrugNamesByCategory'].extMap = [ 'category', 'callback' ];
api['getAllDrugAliases'].external = true;
api['getAllDrugAliases'].extMap = [ 'callback' ];
api['getAllDrugs'].external = true;
api['getAllDrugs'].extMap = [ 'callback' ];
api['getAllCategories'].external = true;
api['getAllCategories'].extMap = [ 'callback' ];
api['getInteraction'].external = true;
api['getInteraction'].extMap = [ 'drugA', 'drugB', 'callback' ];
return api;
};
exports.fetch = function(dbot) {
return api(dbot);
};