var _ = require('lodash'), Promise = require('bluebird'), errors = require('../errors'), api = require('../api'), loader = require('./loader'), // Holds the available apps availableApps = {}; function getInstalledApps() { return api.settings.read({context: {internal: true}, key: 'installedApps'}).then(function (response) { var installed = response.settings[0]; installed.value = installed.value || '[]'; try { installed = JSON.parse(installed.value); } catch (e) { return Promise.reject(e); } return installed; }); } function saveInstalledApps(installedApps) { return getInstalledApps().then(function (currentInstalledApps) { var updatedAppsInstalled = _.uniq(installedApps.concat(currentInstalledApps)); return api.settings.edit({settings: [{key: 'installedApps', value: updatedAppsInstalled}]}, {context: {internal: true}}); }); } module.exports = { init: function () { var appsToLoad; try { // We have to parse the value because it's a string api.settings.read({context: {internal: true}, key: 'activeApps'}).then(function (response) { var aApps = response.settings[0]; appsToLoad = JSON.parse(aApps.value) || []; }); } catch (e) { errors.logError( 'Failed to parse activeApps setting value: ' + e.message, 'Your apps will not be loaded.', 'Check your settings table for typos in the activeApps value. It should look like: ["app-1", "app2"] (double quotes required).' ); return Promise.resolve(); } // Grab all installed apps, install any not already installed that are in appsToLoad. return getInstalledApps().then(function (installedApps) { var loadedApps = {}, recordLoadedApp = function (name, loadedApp) { // After loading the app, add it to our hash of loaded apps loadedApps[name] = loadedApp; return Promise.resolve(loadedApp); }, loadPromises = _.map(appsToLoad, function (app) { // If already installed, just activate the app if (_.contains(installedApps, app)) { return loader.activateAppByName(app).then(function (loadedApp) { return recordLoadedApp(app, loadedApp); }); } // Install, then activate the app return loader.installAppByName(app).then(function () { return loader.activateAppByName(app); }).then(function (loadedApp) { return recordLoadedApp(app, loadedApp); }); }); return Promise.all(loadPromises).then(function () { // Save our installed apps to settings return saveInstalledApps(_.keys(loadedApps)); }).then(function () { // Extend the loadedApps onto the available apps _.extend(availableApps, loadedApps); }).catch(function (err) { errors.logError( err.message || err, 'The app will not be loaded', 'Check with the app creator, or read the app documentation for more details on app requirements' ); }); }); }, availableApps: availableApps };