Add preliminary plugin support

-Plugins can now be enabled via settings.json after dropping the plugin files into the new plugins directory
-Enabling plugins will allow extending the normal functionality of the explorer with new database collections, menus, pages and apis + open up a new url for data to be sent from the plugin to the explorer
-A new plugins section was added to the settings with a definition for the generic-snapshots plugin
-Locale strings are now loaded and shared out via the settings so there is generally no more need to explicitly include the locale.js file
-The locale object has been updated to localization within the explorer
-A number of new locale strings have been added and their values replaced with the locale string within the explorer
-Added plugin support verbiage and a link to the generic-snapshots crowdfunding task to the README
This commit is contained in:
Joe Uhren
2024-06-16 18:58:12 -06:00
parent 7ebdb5e868
commit 788454051c
35 changed files with 1196 additions and 728 deletions
+79 -15
View File
@@ -13,7 +13,6 @@ var mongoose = require('mongoose'),
ClaimAddress = require('../models/claimaddress'),
lib = require('./explorer'),
settings = require('./settings'),
locale = require('./locale'),
fs = require('fs');
function find_address(hash, caseSensitive, cb) {
@@ -130,7 +129,7 @@ function get_market_data(market, coin_symbol, pair_symbol, cb) {
if (fs.existsSync('./lib/markets/' + market + '.js')) {
exMarket = require('./markets/' + market);
exMarket.get_data({coin: coin_symbol, exchange: pair_symbol, api_error_msg: locale.mkt_unexpected_api_data}, function(err, obj) {
exMarket.get_data({coin: coin_symbol, exchange: pair_symbol, api_error_msg: settings.localization.mkt_unexpected_api_data}, function(err, obj) {
return cb(err, obj);
});
} else
@@ -248,7 +247,7 @@ function init_markets(cb) {
// check if exchange trading pair exists in the market collection
if (!exists) {
// exchange doesn't exist in the market collection so add a default definition now
console.log('No %s[%s] entry found. Creating new entry now..', market, split_pair[0] + '/' + split_pair[1]);
console.log(`${settings.localization.creating_initial_entry.replace('{1}', `${market}[${split_pair[0]}/${split_pair[1]}]`)}.. ${settings.localization.please_wait}..`);
module.exports.create_market(split_pair[0], split_pair[1], market, function() {
pairCounter++;
@@ -343,7 +342,7 @@ function init_heavy(cb) {
if (settings.blockchain_specific.heavycoin.enabled == true) {
module.exports.check_heavy(settings.coin.name, function(exists) {
if (exists == false) {
console.log('No heavycoin entry found. Creating new entry now..');
console.log(`${settings.localization.creating_initial_entry.replace('{1}', 'heavycoin')}.. ${settings.localization.please_wait}..`);
module.exports.create_heavy(settings.coin.name, function() {
return cb();
});
@@ -412,6 +411,68 @@ function init_claimaddress(coin, cb) {
});
}
function init_plugins(coin, cb) {
// check if there are any defined plugins in the settings
if (settings.plugins.allowed_plugins != null && settings.plugins.allowed_plugins.length > 0) {
let checkedPlugins = 0;
// loop through all plugins defined in the settings
settings.plugins.allowed_plugins.forEach(function (plugin) {
// check if this plugin is enabled
if (!plugin.enabled) {
checkedPlugins++;
if (checkedPlugins == settings.plugins.allowed_plugins.length)
return cb();
} else {
const pluginName = (plugin.plugin_name == null ? '' : plugin.plugin_name);
// check if the plugin exists in the plugins directory
if (!fs.existsSync(`./plugins/${pluginName}`)) {
console.log(`WARNING: Plugin '${pluginName}' is not installed in the plugins directory`);
checkedPlugins++;
if (checkedPlugins == settings.plugins.allowed_plugins.length)
return cb();
} else {
// check if the plugin's server_functions file exists
if (!fs.existsSync(`./plugins/${pluginName}/lib/server_functions.js`)) {
console.log(`WARNING: Plugin '${pluginName}' is missing the /lib/server_functions.js file`);
checkedPlugins++;
if (checkedPlugins == settings.plugins.allowed_plugins.length)
return cb();
} else {
// load the server_functions.js file from the plugin
const serverFunctions = require(`../plugins/${pluginName}/lib/server_functions`);
// check if the plugin_load function exists
if (typeof serverFunctions.plugin_load !== 'function') {
console.log(`WARNING: Plugin '${pluginName}' is missing the plugin_load function`);
checkedPlugins++;
if (checkedPlugins == settings.plugins.allowed_plugins.length)
return cb();
} else {
// call the plugin_load function to initialize the plugin
serverFunctions.plugin_load(coin, function() {
checkedPlugins++;
if (checkedPlugins == settings.plugins.allowed_plugins.length)
return cb();
});
}
}
}
}
});
} else
return cb();
}
// find masternode by txid and
function find_masternode(txhash, addr, cb) {
Masternode.findOne({ txhash: txhash, addr: addr }).then((masternode) => {
@@ -660,7 +721,7 @@ module.exports = {
});
newStats.save().then(() => {
console.log("Initial stats entry created for %s", coin);
console.log(`${settings.localization.entry_created_successfully.replace('{1}', 'stats').replace('{2}', coin)}`);
return cb();
}).catch((err) => {
console.log(err);
@@ -1014,7 +1075,7 @@ module.exports = {
});
newMarkets.save().then(() => {
console.log("Initial market entry created for %s[%s]", market, coin_symbol + '/' + pair_symbol);
console.log(`${settings.localization.entry_created_successfully.replace('{1}', 'market').replace('{2}', `${market}[${coin_symbol}/${pair_symbol}]`)}`);
return cb();
}).catch((err) => {
console.log(err);
@@ -1054,7 +1115,7 @@ module.exports = {
});
newRichlist.save().then(() => {
console.log("Initial richlist entry created for %s", coin);
console.log(`${settings.localization.entry_created_successfully.replace('{1}', 'richlist').replace('{2}', coin)}`);
return cb();
}).catch((err) => {
console.log(err);
@@ -1096,7 +1157,7 @@ module.exports = {
});
newHeavy.save().then(() => {
console.log("Initial heavycoin entry created for %s", coin);
console.log(`${settings.localization.entry_created_successfully.replace('{1}', 'heavycoin').replace('{2}', coin)}`);
return cb();
}).catch((err) => {
console.log(err);
@@ -1879,7 +1940,7 @@ module.exports = {
},
initialize_data_startup: function(cb) {
console.log('Initializing database.. Please wait...');
console.log(`${settings.localization.initializing_database}.. ${settings.localization.please_wait}..`);
// check if stats collection is initialized
module.exports.check_stats(settings.coin.name, function(stats_exists) {
@@ -1887,7 +1948,7 @@ module.exports = {
// determine if stats collection already exists
if (stats_exists == false) {
console.log('No stats entry found. Creating new entry now..');
console.log(`${settings.localization.creating_initial_entry.replace('{1}', 'stats')}.. ${settings.localization.please_wait}..`);
skip = false;
}
@@ -1909,7 +1970,7 @@ module.exports = {
// determine if richlist collection already exists
if (richlist_exists == false) {
console.log('No richlist entry found. Creating new entry now..');
console.log(`${settings.localization.creating_initial_entry.replace('{1}', 'richlist')}.. ${settings.localization.please_wait}..`);
skip = false;
}
@@ -1919,9 +1980,12 @@ module.exports = {
init_heavy(function() {
// check and initialize the claimaddress collection
init_claimaddress(settings.coin.name, function() {
// finished initializing startup data
console.log('Database initialization complete');
return cb();
// initialize all enabled plugins
init_plugins(settings.coin.name, function() {
// finished initializing startup data
console.log('Database initialization complete');
return cb();
});
});
});
});
@@ -1951,7 +2015,7 @@ module.exports = {
save_tx: function(txid, blockheight, block, cb) {
lib.get_rawtransaction(txid, function(tx) {
if (tx && tx != 'There was an error. Check your console.') {
if (tx && tx != `${settings.localization.ex_error}: ${settings.localization.check_console}`) {
lib.prepare_vin(tx, function(vin, tx_type_vin) {
lib.prepare_vout(tx.vout, txid, vin, ((!settings.blockchain_specific.zksnarks.enabled || typeof tx.vjoinsplit === 'undefined' || tx.vjoinsplit == null) ? [] : tx.vjoinsplit), function(vout, nvin, tx_type_vout) {
lib.syncLoop(nvin.length, function (loop) {