mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-27 22:49:56 -05:00
7b761a8751
no issue Adds new canary api endpoint, currently replicating v2 endpoint but paving way for future updates to new version
130 lines
4.9 KiB
JavaScript
130 lines
4.9 KiB
JavaScript
const _ = require('lodash');
|
|
const moment = require('moment');
|
|
const config = require('../../config');
|
|
const models = require('../../models');
|
|
const urlUtils = require('../../lib/url-utils');
|
|
const common = require('../../lib/common');
|
|
const api = require('./index');
|
|
|
|
module.exports = {
|
|
docName: 'schedules',
|
|
publish: {
|
|
headers: {},
|
|
options: [
|
|
'id',
|
|
'resource'
|
|
],
|
|
data: [
|
|
'force'
|
|
],
|
|
validation: {
|
|
options: {
|
|
id: {
|
|
required: true
|
|
},
|
|
resource: {
|
|
required: true,
|
|
values: ['posts', 'pages']
|
|
}
|
|
}
|
|
},
|
|
permissions: {
|
|
docName: 'posts'
|
|
},
|
|
query(frame) {
|
|
let resource;
|
|
const resourceType = frame.options.resource;
|
|
const publishAPostBySchedulerToleranceInMinutes = config.get('times').publishAPostBySchedulerToleranceInMinutes;
|
|
|
|
return models.Base.transaction((transacting) => {
|
|
const options = {
|
|
transacting: transacting,
|
|
status: 'scheduled',
|
|
forUpdate: true,
|
|
id: frame.options.id,
|
|
context: {
|
|
internal: true
|
|
}
|
|
};
|
|
|
|
return api[resourceType].read({id: frame.options.id}, options)
|
|
.then((result) => {
|
|
resource = result[resourceType][0];
|
|
const publishedAtMoment = moment(resource.published_at);
|
|
|
|
if (publishedAtMoment.diff(moment(), 'minutes') > publishAPostBySchedulerToleranceInMinutes) {
|
|
return Promise.reject(new common.errors.NotFoundError({message: common.i18n.t('errors.api.job.notFound')}));
|
|
}
|
|
|
|
if (publishedAtMoment.diff(moment(), 'minutes') < publishAPostBySchedulerToleranceInMinutes * -1 && frame.data.force !== true) {
|
|
return Promise.reject(new common.errors.NotFoundError({message: common.i18n.t('errors.api.job.publishInThePast')}));
|
|
}
|
|
|
|
const editedResource = {};
|
|
editedResource[resourceType] = [{
|
|
status: 'published',
|
|
updated_at: moment(resource.updated_at).toISOString(true)
|
|
}];
|
|
|
|
return api[resourceType].edit(
|
|
editedResource,
|
|
_.pick(options, ['context', 'id', 'transacting', 'forUpdate'])
|
|
);
|
|
})
|
|
.then((result) => {
|
|
const scheduledResource = result[resourceType][0];
|
|
|
|
if (
|
|
(scheduledResource.status === 'published' && resource.status !== 'published') ||
|
|
(scheduledResource.status === 'draft' && resource.status === 'published')
|
|
) {
|
|
this.headers.cacheInvalidate = true;
|
|
} else if (
|
|
(scheduledResource.status === 'draft' && resource.status !== 'published') ||
|
|
(scheduledResource.status === 'scheduled' && resource.status !== 'scheduled')
|
|
) {
|
|
this.headers.cacheInvalidate = {
|
|
value: urlUtils.urlFor({
|
|
relativeUrl: urlUtils.urlJoin('/p', scheduledResource.uuid, '/')
|
|
})
|
|
};
|
|
} else {
|
|
this.headers.cacheInvalidate = false;
|
|
}
|
|
|
|
return result;
|
|
});
|
|
});
|
|
}
|
|
},
|
|
|
|
getScheduled: {
|
|
// NOTE: this method is for internal use only by DefaultScheduler
|
|
// it is not exposed anywhere!
|
|
permissions: false,
|
|
validation: {
|
|
options: {
|
|
resource: {
|
|
required: true,
|
|
values: ['posts', 'pages']
|
|
}
|
|
}
|
|
},
|
|
query(frame) {
|
|
const resourceType = frame.options.resource;
|
|
const resourceModel = (resourceType === 'posts') ? 'Post' : 'Page';
|
|
|
|
const cleanOptions = {};
|
|
cleanOptions.filter = 'status:scheduled';
|
|
cleanOptions.columns = ['id', 'published_at', 'created_at'];
|
|
|
|
return models[resourceModel].findAll(cleanOptions)
|
|
.then((result) => {
|
|
let response = {};
|
|
response[resourceType] = result;
|
|
|
|
return response;
|
|
});
|
|
}
|
|
}
|
|
};
|