mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-27 22:49:56 -05:00
e370d33378
refs https://github.com/TryGhost/Team/issues/694 - This refactor is not ideal but moves us closer to the desired form of class with injectable (and testable) parameters. Allowed to refactor the test slightly so at least we can check if schedulerd subscribed events work and if they trigger the adapter with correct data - Ideally the api/model calls shoudl be abstracted away as well, but that's for another time - Also got rid of completely pointless "adapters/scheduling" unit test. All it was checking was if the "init" method was called int the passe in object
78 lines
3.3 KiB
JavaScript
78 lines
3.3 KiB
JavaScript
const moment = require('moment');
|
|
const errors = require('@tryghost/errors');
|
|
|
|
const urlUtils = require('../../../../shared/url-utils');
|
|
const getSignedAdminToken = require('./scheduling-auth-token');
|
|
|
|
class PostScheduler {
|
|
constructor({apiUrl, integration, adapter, scheduledResources, events} = {}) {
|
|
if (!apiUrl) {
|
|
throw new errors.IncorrectUsageError({message: 'post-scheduling: no apiUrl was provided'});
|
|
}
|
|
|
|
if (Object.keys(scheduledResources).length) {
|
|
// Reschedules all scheduled resources on boot
|
|
// NOTE: We are using reschedule, because custom scheduling adapter could use a database, which needs to be updated
|
|
// and not an in-process implementation!
|
|
Object.keys(scheduledResources).forEach((resourceType) => {
|
|
scheduledResources[resourceType].forEach((model) => {
|
|
adapter.unschedule(this.normalize({model, apiUrl, integration, resourceType}, 'unscheduled'), {bootstrap: true});
|
|
adapter.schedule(this.normalize({model, apiUrl, integration, resourceType}));
|
|
});
|
|
});
|
|
}
|
|
|
|
adapter.run();
|
|
|
|
const SCHEDULED_RESOURCES = ['post', 'page'];
|
|
SCHEDULED_RESOURCES.forEach((resource) => {
|
|
events.on(`${resource}.scheduled`, (model) => {
|
|
adapter.schedule(this.normalize({model, apiUrl, integration, resourceType: resource}));
|
|
});
|
|
|
|
/** We want to do reschedule as (unschedule + schedule) due to how token(+url) is generated
|
|
* We want to first remove existing schedule by generating a matching token(+url)
|
|
* followed by generating a new token(+url) for the new schedule
|
|
*/
|
|
events.on(`${resource}.rescheduled`, (model) => {
|
|
adapter.unschedule(this.normalize({model, apiUrl, integration, resourceType: resource}, 'unscheduled'));
|
|
adapter.schedule(this.normalize({model, apiUrl, integration, resourceType: resource}));
|
|
});
|
|
|
|
events.on(`${resource}.unscheduled`, (model) => {
|
|
adapter.unschedule(this.normalize({model, apiUrl, integration, resourceType: resource}, 'unscheduled'));
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @description Normalize model data into scheduler notation.
|
|
* @param {Object} options
|
|
* @return {Object}
|
|
*/
|
|
normalize({model, apiUrl, resourceType, integration}, event = '') {
|
|
const resource = `${resourceType}s`;
|
|
const publishedAt = (event === 'unscheduled') ? model.previous('published_at') : model.get('published_at');
|
|
const signedAdminToken = getSignedAdminToken({
|
|
publishedAt,
|
|
apiUrl,
|
|
key: {
|
|
id: integration.api_keys[0].id,
|
|
secret: integration.api_keys[0].secret
|
|
}
|
|
});
|
|
let url = `${urlUtils.urlJoin(apiUrl, 'schedules', resource, model.get('id'))}/?token=${signedAdminToken}`;
|
|
|
|
return {
|
|
// NOTE: The scheduler expects a unix timestamp.
|
|
time: moment(publishedAt).valueOf(),
|
|
url: url,
|
|
extra: {
|
|
httpMethod: 'PUT',
|
|
oldTime: model.previous('published_at') ? moment(model.previous('published_at')).valueOf() : null
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = PostScheduler;
|