0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-06 22:40:14 -05:00

Add XML-RPC ping

closes #2148
- Added core/server/xmlrpc.js
- Hook into post::saved to ping when a published post gets saved
- Added node package to hook into http requests
This commit is contained in:
Fabian Becker 2014-03-14 22:10:50 +00:00
parent ec3aabb384
commit 9e7469e3ea
4 changed files with 121 additions and 2 deletions

View file

@ -11,6 +11,7 @@ var _ = require('lodash'),
Tags = require('./tag').Tags,
ghostBookshelf = require('./base'),
validation = require('../data/validation'),
xmlrpc = require('../xmlrpc'),
Post,
Posts;
@ -29,7 +30,12 @@ Post = ghostBookshelf.Model.extend({
initialize: function () {
var self = this;
this.on('creating', this.creating, this);
this.on('saved', this.updateTags, this);
this.on('saved', function (model, attributes, options) {
if (model.get('status') === 'published') {
xmlrpc.ping(model.attributes);
}
return self.updateTags(model, attributes, options);
});
this.on('saving', function (model, attributes, options) {
return when(self.saving(model, attributes, options)).then(function () {
return self.validate(model, attributes, options);

65
core/server/xmlrpc.js Normal file
View file

@ -0,0 +1,65 @@
var _ = require('lodash'),
config = require('./config'),
errors = require('./errorHandling'),
http = require('http'),
xml = require('xml'),
pingList;
// ToDo: Make this configurable
pingList = [
{ host: 'blogsearch.google.com', path: '/ping/RPC2' },
{ host: 'rpc.pingomatic.com', path: '/' }
];
function ping(post) {
var pingXML,
title = post.title;
// Only ping when in production and not a page
if (process.env.NODE_ENV !== 'production' || post.page) {
return;
}
// Need to require here because of circular dependency
return config.urlForPost(require('./api').settings, post, true).then(function (url) {
// Build XML object.
pingXML = xml({
methodCall: [
{ methodName: 'weblogUpdate.ping' },
{
params: [{
param: [{ value: [{ string: title }]}],
}, {
param: [{ value: [{ string: url }]}],
}]
}
]
}, {declaration: true});
// Ping each of the defined services.
_.each(pingList, function (pingHost) {
var options = {
hostname: pingHost.host,
path: pingHost.path,
method: 'POST'
},
req;
req = http.request(options);
req.write(pingXML);
req.on('error', function (error) {
errors.logError(
error,
"Pinging services for updates on your blog failed, your blog will continue to function.",
"If you get this error repeatedly, please seek help from https://ghost.org/forum."
);
});
req.end();
});
});
}
module.exports = {
ping: ping
};

View file

@ -0,0 +1,46 @@
/*globals describe, beforeEach, afterEach, it*/
var assert = require('assert'),
http = require('http'),
nock = require('nock'),
settings = require('../../server/api').settings;
should = require('should'),
sinon = require('sinon'),
testUtils = require('../utils'),
when = require('when'),
xmlrpc = require('../../server/xmlrpc'),
// storing current environment
currentEnv = process.env.NODE_ENV;
describe('XMLRPC', function () {
var sandbox;
beforeEach(function () {
sandbox = sinon.sandbox.create();
// give environment a value that will ping
process.env.NODE_ENV = "production";
});
afterEach(function () {
sandbox.restore();
// reset the environment
process.env.NODE_ENV = currentEnv;
});
it('should execute two pings', function (done) {
var ping1 = nock('http://blogsearch.google.com').post('/ping/RPC2').reply(200),
ping2 = nock('http://rpc.pingomatic.com').post('/').reply(200),
testPost = testUtils.DataGenerator.Content.posts[2],
settingsStub = sandbox.stub(settings, 'read', function () {
return when({value: '/:slug/'});
});
xmlrpc.ping(testPost).then(function () {
ping1.isDone().should.be.true;
ping2.isDone().should.be.true;
done();
});
});
});

View file

@ -52,7 +52,8 @@
"sqlite3": "2.2.0",
"unidecode": "0.1.3",
"validator": "3.4.0",
"when": "2.7.0"
"when": "2.7.0",
"xml": "0.0.12"
},
"optionalDependencies": {
"mysql": "2.1.1"
@ -77,6 +78,7 @@
"grunt-update-submodules": "~0.2.1",
"matchdep": "~0.3.0",
"mocha": "~1.15.1",
"nock": "0.27.2",
"rewire": "~2.0.0",
"request": "~2.29.0",
"require-dir": "~0.1.0",