Extracted frontend code from settings API controllers (#10797)

* Moved settings#upload method out of settings controller

* Moved out code from download to serve method

* Moved API v0.1 settings upload/downalod routes.yaml methods to use setting handler service

* Reverted unintended change

* Moved RoutesHandler into settings module

- To keep in convention with settings described in - https://github.com/TryGhost/Ghost/issues/9528 , extracted routes handler into separate settings folder

* Frontend settings for API v0.1

* Renamed 'routes' to 'dynamic-routing'

* Renamved activate/serve methods as suggested in discussions

* Moved settings dynamicRouting to routing.settings
This commit is contained in:
Naz Gargol 2019-06-21 16:52:07 +02:00 committed by GitHub
commit 8ae5db9922
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 110 additions and 134 deletions

View File

@ -7,6 +7,10 @@ module.exports = {
return require('./registry');
},
get settings() {
return require('./settings');
},
get helpers() {
return require('./helpers');
},

View File

@ -0,0 +1,100 @@
const moment = require('moment-timezone');
const fs = require('fs-extra');
const path = require('path');
const urlService = require('../url');
const common = require('../../../server/lib/common');
const config = require('../../../server/config');
/**
* The `routes.yaml` file offers a way to configure your Ghost blog. It's currently a setting feature
* we have added. That's why the `routes.yaml` file is treated as a "setting" right now.
* If we want to add single permissions for this file (e.g. upload/download routes.yaml), we can add later.
*
* How does it work?
*
* - we first reset all url generators (each url generator belongs to one express router)
* - we don't destroy the resources, we only release them (this avoids reloading all resources from the db again)
* - then we reload the whole site app, which will reset all routers and re-create the url generators
*/
const setFromFilePath = (filePath) => {
const settingsPath = config.getContentPath('settings');
const backupRoutesPath = path.join(settingsPath, `routes-${moment().format('YYYY-MM-DD-HH-mm-ss')}.yaml`);
return fs.copy(`${settingsPath}/routes.yaml`, backupRoutesPath)
.then(() => {
return fs.copy(filePath, `${settingsPath}/routes.yaml`);
})
.then(() => {
urlService.resetGenerators({releaseResourcesOnly: true});
})
.then(() => {
const siteApp = require('../../../server/web/site/app');
const bringBackValidRoutes = () => {
urlService.resetGenerators({releaseResourcesOnly: true});
return fs.copy(backupRoutesPath, `${settingsPath}/routes.yaml`)
.then(() => {
return siteApp.reload();
});
};
try {
siteApp.reload();
} catch (err) {
return bringBackValidRoutes()
.finally(() => {
throw err;
});
}
let tries = 0;
function isBlogRunning() {
return Promise.delay(1000)
.then(() => {
if (!urlService.hasFinished()) {
if (tries > 5) {
throw new common.errors.InternalServerError({
message: 'Could not load routes.yaml file.'
});
}
tries = tries + 1;
return isBlogRunning();
}
});
}
return isBlogRunning()
.catch((err) => {
return bringBackValidRoutes()
.finally(() => {
throw err;
});
});
});
};
const get = () => {
const routesPath = path.join(config.getContentPath('settings'), 'routes.yaml');
return fs.readFile(routesPath, 'utf-8')
.catch((err) => {
if (err.code === 'ENOENT') {
return Promise.resolve([]);
}
if (common.errors.utils.isIgnitionError(err)) {
throw err;
}
throw new common.errors.NotFoundError({
err: err
});
});
};
module.exports.setFromFilePath = setFromFilePath;
module.exports.get = get;

View File

@ -2,14 +2,10 @@
// RESTful API for the Setting resource
const Promise = require('bluebird'),
_ = require('lodash'),
moment = require('moment-timezone'),
fs = require('fs-extra'),
path = require('path'),
config = require('../../config'),
models = require('../../models'),
canThis = require('../../services/permissions').canThis,
localUtils = require('./utils'),
urlService = require('../../../frontend/services/url'),
routing = require('../../../frontend/services/routing'),
common = require('../../lib/common'),
settingsCache = require('../../services/settings/cache'),
docName = 'settings';
@ -255,67 +251,17 @@ settings = {
});
},
/**
* The `routes.yaml` file offers a way to configure your Ghost blog. It's currently a setting feature
* we have added. That's why the `routes.yaml` file is treated as a "setting" right now.
* If we want to add single permissions for this file (e.g. upload/download routes.yaml), we can add later.
*
* How does it work?
*
* - we first reset all url generators (each url generator belongs to one express router)
* - we don't destroy the resources, we only release them (this avoids reloading all resources from the db again)
* - then we reload the whole site app, which will reset all routers and re-create the url generators
*/
upload(options) {
const backupRoutesPath = path.join(config.getContentPath('settings'), `routes-${moment().format('YYYY-MM-DD-HH-mm-ss')}.yaml`);
return localUtils.handlePermissions('settings', 'edit')(options)
.then(() => {
return fs.copy(`${config.getContentPath('settings')}/routes.yaml`, backupRoutesPath);
})
.then(() => {
return fs.copy(options.path, `${config.getContentPath('settings')}/routes.yaml`);
})
.then(() => {
urlService.resetGenerators({releaseResourcesOnly: true});
})
.then(() => {
const siteApp = require('../../web/site/app');
try {
return siteApp.reload();
} catch (err) {
// bring back backup, otherwise your Ghost blog is broken
return fs.copy(backupRoutesPath, `${config.getContentPath('settings')}/routes.yaml`)
.then(() => {
return siteApp.reload();
})
.then(() => {
throw err;
});
}
return routing.settings.setFromFilePath(options.path);
});
},
download(options) {
const routesPath = path.join(config.getContentPath('settings'), 'routes.yaml');
return localUtils.handlePermissions('settings', 'browse')(options)
.then(() => {
return fs.readFile(routesPath, 'utf-8');
})
.catch((err) => {
if (err.code === 'ENOENT') {
return Promise.resolve([]);
}
if (common.errors.utils.isIgnitionError(err)) {
throw err;
}
throw new common.errors.NotFoundError({
err: err
});
return routing.settings.get();
});
}
};

View File

@ -1,11 +1,7 @@
const Promise = require('bluebird');
const _ = require('lodash');
const moment = require('moment-timezone');
const fs = require('fs-extra');
const path = require('path');
const config = require('../../config');
const models = require('../../models');
const urlService = require('../../../frontend/services/url');
const routing = require('../../../frontend/services/routing');
const common = require('../../lib/common');
const settingsCache = require('../../services/settings/cache');
@ -151,62 +147,7 @@ module.exports = {
method: 'edit'
},
query(frame) {
const backupRoutesPath = path.join(config.getContentPath('settings'), `routes-${moment().format('YYYY-MM-DD-HH-mm-ss')}.yaml`);
return fs.copy(`${config.getContentPath('settings')}/routes.yaml`, backupRoutesPath)
.then(() => {
return fs.copy(frame.file.path, `${config.getContentPath('settings')}/routes.yaml`);
})
.then(() => {
urlService.resetGenerators({releaseResourcesOnly: true});
})
.then(() => {
const siteApp = require('../../web/site/app');
const bringBackValidRoutes = () => {
urlService.resetGenerators({releaseResourcesOnly: true});
return fs.copy(backupRoutesPath, `${config.getContentPath('settings')}/routes.yaml`)
.then(() => {
return siteApp.reload();
});
};
try {
siteApp.reload();
} catch (err) {
return bringBackValidRoutes()
.finally(() => {
throw err;
});
}
let tries = 0;
function isBlogRunning() {
return Promise.delay(1000)
.then(() => {
if (!urlService.hasFinished()) {
if (tries > 5) {
throw new common.errors.InternalServerError({
message: 'Could not load routes.yaml file.'
});
}
tries = tries + 1;
return isBlogRunning();
}
});
}
return isBlogRunning()
.catch((err) => {
return bringBackValidRoutes()
.finally(() => {
throw err;
});
});
});
return routing.settings.setFromFilePath(frame.file.path);
}
},
@ -224,22 +165,7 @@ module.exports = {
method: 'browse'
},
query() {
const routesPath = path.join(config.getContentPath('settings'), 'routes.yaml');
return fs.readFile(routesPath, 'utf-8')
.catch((err) => {
if (err.code === 'ENOENT') {
return Promise.resolve([]);
}
if (common.errors.utils.isIgnitionError(err)) {
throw err;
}
throw new common.errors.NotFoundError({
err: err
});
});
return routing.settings.get();
}
}
};