mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-30 14:22:07 +03:00
abda6e6338
closes #10773 - The refactoring is a substitute for `urlService.utils` used previously throughout the codebase and now extracted into the separate module in Ghost-SDK - Added url-utils stubbing utility for test suites - Some tests had to be refactored to avoid double mocks (when url's are being reset inside of rested 'describe' groups)
120 lines
3.7 KiB
JavaScript
120 lines
3.7 KiB
JavaScript
const Promise = require('bluebird'),
|
|
moment = require('moment'),
|
|
localUtils = require('../utils'),
|
|
common = require('../../../lib/common'),
|
|
models = require('../../../models'),
|
|
urlUtils = require('../../../lib/url-utils'),
|
|
_private = {};
|
|
|
|
/**
|
|
* @description Normalize model data into scheduler notation.
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
_private.normalize = function normalize(options) {
|
|
const {model, apiUrl, client} = options;
|
|
|
|
return {
|
|
// NOTE: The scheduler expects a unix timestmap.
|
|
time: moment(model.get('published_at')).valueOf(),
|
|
// @TODO: We are still using API v0.1
|
|
url: `${urlUtils.urlJoin(apiUrl, 'schedules', 'posts', model.get('id'))}?client_id=${client.get('slug')}&client_secret=${client.get('secret')}`,
|
|
extra: {
|
|
httpMethod: 'PUT',
|
|
oldTime: model.previous('published_at') ? moment(model.previous('published_at')).valueOf() : null
|
|
}
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @description Load the client credentials for v0.1 API.
|
|
*
|
|
* @TODO: Remove when we drop v0.1. API v2 uses integrations.
|
|
* @return {Promise}
|
|
*/
|
|
_private.loadClient = function loadClient() {
|
|
return models.Client.findOne({slug: 'ghost-scheduler'}, {columns: ['slug', 'secret']});
|
|
};
|
|
|
|
/**
|
|
* @description Load all scheduled posts from database.
|
|
* @return {Promise}
|
|
*/
|
|
_private.loadScheduledPosts = function () {
|
|
const api = require('../../../api');
|
|
return api.schedules.getScheduledPosts()
|
|
.then((result) => {
|
|
return result.posts || [];
|
|
});
|
|
};
|
|
|
|
/**
|
|
* @description Initialise post scheduling.
|
|
* @param {Object} options
|
|
* @return {*}
|
|
*/
|
|
exports.init = function init(options = {}) {
|
|
const {apiUrl} = options;
|
|
let adapter = null,
|
|
client = null;
|
|
|
|
if (!Object.keys(options).length) {
|
|
return Promise.reject(new common.errors.IncorrectUsageError({message: 'post-scheduling: no config was provided'}));
|
|
}
|
|
|
|
if (!apiUrl) {
|
|
return Promise.reject(new common.errors.IncorrectUsageError({message: 'post-scheduling: no apiUrl was provided'}));
|
|
}
|
|
|
|
return _private.loadClient()
|
|
.then((_client) => {
|
|
client = _client;
|
|
return localUtils.createAdapter(options);
|
|
})
|
|
.then((_adapter) => {
|
|
adapter = _adapter;
|
|
|
|
if (!adapter.rescheduleOnBoot) {
|
|
return [];
|
|
}
|
|
|
|
return _private.loadScheduledPosts();
|
|
})
|
|
.then((scheduledPosts) => {
|
|
if (!scheduledPosts.length) {
|
|
return;
|
|
}
|
|
|
|
scheduledPosts.forEach((model) => {
|
|
// NOTE: We are using reschedule, because custom scheduling adapter could use a database, which needs to be updated
|
|
// and not an in-process implementation!
|
|
adapter.reschedule(_private.normalize({model, apiUrl, client}), {bootstrap: true});
|
|
});
|
|
})
|
|
.then(() => {
|
|
adapter.run();
|
|
})
|
|
.then(() => {
|
|
common.events.onMany([
|
|
'post.scheduled',
|
|
'page.scheduled'
|
|
], (model) => {
|
|
adapter.schedule(_private.normalize({model, apiUrl, client}));
|
|
});
|
|
|
|
common.events.onMany([
|
|
'post.rescheduled',
|
|
'page.rescheduled'
|
|
], (model) => {
|
|
adapter.reschedule(_private.normalize({model, apiUrl, client}));
|
|
});
|
|
|
|
common.events.onMany([
|
|
'post.unscheduled',
|
|
'page.unscheduled'
|
|
], (model) => {
|
|
adapter.unschedule(_private.normalize({model, apiUrl, client}));
|
|
});
|
|
});
|
|
};
|